diff options
Diffstat (limited to 'src')
117 files changed, 6162 insertions, 3884 deletions
diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 72ce8e09b97..46f5c5ef287 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -45,7 +45,6 @@ use layout::wrapper::{Before, BeforeBlock, After, AfterBlock, Normal}; use gfx::display_list::OpaqueNode; use gfx::font_context::FontContext; -use script::dom::bindings::codegen::InheritTypes::TextCast; use script::dom::bindings::js::JS; use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId}; use script::dom::element::{HTMLObjectElementTypeId}; @@ -1064,8 +1063,8 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { match self.type_id() { Some(TextNodeTypeId) => { unsafe { - let text: JS<Text> = TextCast::to(self.get_jsmanaged()).unwrap(); - if !is_whitespace(text.get().characterdata.data) { + let text: JS<Text> = self.get_jsmanaged().transmute_copy(); + if !is_whitespace((*text.unsafe_get()).characterdata.data) { return false } diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index 162c06d52a9..4aa10c3ba63 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -37,10 +37,11 @@ use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived}; use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementDerived, TextDerived}; use script::dom::bindings::js::JS; use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId}; -use script::dom::element::{HTMLLinkElementTypeId}; +use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::htmliframeelement::HTMLIFrameElement; -use script::dom::htmlimageelement::HTMLImageElement; -use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId, NodeHelpers}; +use script::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers}; +use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId}; +use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers}; use script::dom::text::Text; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_util::namespace; @@ -95,7 +96,7 @@ pub trait TLayoutNode { fail!("not an image!") } let image_element: JS<HTMLImageElement> = self.get_jsmanaged().transmute_copy(); - (*image_element.unsafe_get()).image().as_ref().map(|url| (*url).clone()) + image_element.image().as_ref().map(|url| (*url).clone()) } } @@ -163,7 +164,9 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { } fn type_id(&self) -> Option<NodeTypeId> { - Some(self.node.type_id()) + unsafe { + Some(self.node.type_id_for_layout()) + } } unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> { @@ -172,7 +175,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn first_child(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node)) + self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node)) } } @@ -221,19 +224,19 @@ impl<'ln> LayoutNode<'ln> { impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { fn parent_node(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.get().parent_node_ref().map(|node| self.new_with_this_lifetime(node)) + self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(node)) } } fn prev_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.get().prev_sibling_ref().map(|node| self.new_with_this_lifetime(node)) + self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(node)) } } fn next_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.get().next_sibling_ref().map(|node| self.new_with_this_lifetime(node)) + self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(node)) } } @@ -241,8 +244,9 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { #[inline] fn as_element(&self) -> LayoutElement<'ln> { unsafe { + assert!(self.node.is_element_for_layout()); let elem: JS<Element> = self.node.transmute_copy(); - let element = elem.get(); + let element = &*elem.unsafe_get(); LayoutElement { element: cast::transmute_region(element), } @@ -258,9 +262,9 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { } fn match_attr(&self, attr: &AttrSelector, test: |&str| -> bool) -> bool { - let element = self.as_element(); let name = unsafe { - if element.element.html_element_in_html_document_for_layout() { + let element: JS<Element> = self.node.transmute_copy(); + if element.html_element_in_html_document_for_layout() { attr.lower_name.as_slice() } else { attr.name.as_slice() @@ -268,6 +272,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { }; match attr.namespace { SpecificNamespace(ref ns) => { + let element = self.as_element(); element.get_attr(ns, name) .map_or(false, |attr| test(attr)) }, @@ -459,7 +464,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { } unsafe { - self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node)) + self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node)) } } @@ -509,10 +514,10 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { /// Returns the next sibling of this node. Unsafe and private because this can lead to races. unsafe fn next_sibling(&self) -> Option<ThreadSafeLayoutNode<'ln>> { if self.pseudo == Before || self.pseudo == BeforeBlock { - return self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node)) + return self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node)) } - self.node.get().next_sibling_ref().map(|node| self.new_with_this_lifetime(node)) + self.get_jsmanaged().next_sibling_ref().map(|node| self.new_with_this_lifetime(node)) } /// Returns an iterator over this node's children. @@ -527,7 +532,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { #[inline] pub fn as_element(&self) -> ThreadSafeLayoutElement { unsafe { - let elem: JS<Element> = self.node.get_jsmanaged().transmute_copy(); + assert!(self.get_jsmanaged().is_element_for_layout()); + let elem: JS<Element> = self.get_jsmanaged().transmute_copy(); let element = elem.unsafe_get(); // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // implementations. diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs index 0ca2fb2889e..4822de7eb07 100644 --- a/src/components/script/dom/attr.rs +++ b/src/components/script/dom/attr.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::AttrBinding; use dom::bindings::codegen::InheritTypes::NodeCast; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::Element; use dom::node::Node; @@ -45,7 +45,7 @@ impl Reflectable for Attr { impl Attr { fn new_inherited(local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>, owner: JS<Element>) -> Attr { + prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr { Attr { reflector_: Reflector::new(), local_name: local_name, @@ -53,25 +53,26 @@ impl Attr { name: name, //TODO: Intern attribute names namespace: namespace, prefix: prefix, - owner: owner, + owner: owner.unrooted(), } } - pub fn new(window: &JS<Window>, local_name: DOMString, value: DOMString, + pub fn new(window: &JSRef<Window>, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>, owner: JS<Element>) -> JS<Attr> { + prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> { let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner); reflect_dom_object(~attr, window, AttrBinding::Wrap) } pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) { - let node: JS<Node> = NodeCast::from(&self.owner); + let mut owner = self.owner.root(); + let node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *owner); let namespace_is_null = self.namespace == namespace::Null; 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.clone()); } } FirstSetAttr => {} @@ -80,7 +81,7 @@ 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.clone()); } } @@ -89,31 +90,40 @@ impl Attr { } } -impl Attr { - pub fn LocalName(&self) -> DOMString { +pub trait AttrMethods { + fn LocalName(&self) -> DOMString; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, value: DOMString); + fn Name(&self) -> DOMString; + fn GetNamespaceURI(&self) -> Option<DOMString>; + fn GetPrefix(&self) -> Option<DOMString>; +} + +impl<'a> AttrMethods for JSRef<'a, Attr> { + fn LocalName(&self) -> DOMString { self.local_name.clone() } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { self.value.clone() } - pub fn SetValue(&mut self, value: DOMString) { + fn SetValue(&mut self, value: DOMString) { self.set_value(ReplacedAttr, value); } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { self.name.clone() } - pub fn GetNamespaceURI(&self) -> Option<DOMString> { + fn GetNamespaceURI(&self) -> Option<DOMString> { match self.namespace.to_str() { "" => None, url => Some(url.to_owned()), } } - pub fn GetPrefix(&self) -> Option<DOMString> { + fn GetPrefix(&self) -> Option<DOMString> { self.prefix.clone() } } diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs index cfa6c2c083f..e707a42b13f 100644 --- a/src/components/script/dom/attrlist.rs +++ b/src/components/script/dom/attrlist.rs @@ -4,7 +4,7 @@ use dom::attr::Attr; use dom::bindings::codegen::BindingDeclarations::AttrListBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::Element; use dom::window::Window; @@ -17,28 +17,36 @@ pub struct AttrList { } impl AttrList { - pub fn new_inherited(window: JS<Window>, elem: JS<Element>) -> AttrList { + pub fn new_inherited(window: &JSRef<Window>, elem: &JSRef<Element>) -> AttrList { AttrList { reflector_: Reflector::new(), - window: window, - owner: elem + window: window.unrooted(), + owner: elem.unrooted(), } } - pub fn new(window: &JS<Window>, elem: &JS<Element>) -> JS<AttrList> { - reflect_dom_object(~AttrList::new_inherited(window.clone(), elem.clone()), + pub fn new(window: &JSRef<Window>, elem: &JSRef<Element>) -> Temporary<AttrList> { + reflect_dom_object(~AttrList::new_inherited(window, elem), window, AttrListBinding::Wrap) } +} + +pub trait AttrListMethods { + fn Length(&self) -> u32; + fn Item(&self, index: u32) -> Option<Temporary<Attr>>; + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Attr>>; +} - pub fn Length(&self) -> u32 { - self.owner.get().attrs.len() as u32 +impl<'a> AttrListMethods for JSRef<'a, AttrList> { + fn Length(&self) -> u32 { + self.owner.root().attrs.len() as u32 } - pub fn Item(&self, index: u32) -> Option<JS<Attr>> { - self.owner.get().attrs.as_slice().get(index as uint).map(|x| x.clone()) + fn Item(&self, index: u32) -> Option<Temporary<Attr>> { + self.owner.root().attrs.as_slice().get(index as uint).map(|x| Temporary::new(x.clone())) } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> { + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Attr>> { let item = self.Item(index); *found = item.is_some(); item diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index 053fabae1b2..c41856ccf86 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -9,8 +9,6 @@ # The configuration table maps each interface name to a |descriptor|. # # Valid fields for all descriptors: -# * needsAbstract: a list of members that require a JS<>-wrapped version of -# self to be passed to the native code. # * createGlobal: True for global objects. # * outerObjectHook: string to use in place of default value for outerObject and thisObject # JS class hooks @@ -26,123 +24,44 @@ DOMInterfaces = { 'ClientRect': {}, 'ClientRectList': {}, 'Console': {}, -'Document': { - 'needsAbstract': [ - 'adoptNode', - 'anchors', - 'applets', - 'body', - 'children', - 'createComment', - 'createDocumentFragment', - 'createElement', - 'createElementNS', - 'createProcessingInstruction', - 'createTextNode', - 'embeds', - 'forms', - 'getElementsByClassName', - 'getElementsByTagName', - 'getElementsByTagNameNS', - 'images', - 'importNode', - 'links', - 'location', - 'plugins', - 'scripts', - 'title', - ], -}, +'Document': {}, 'DOMException': {}, 'DOMImplementation': {}, 'DOMParser': {}, -'Element': { - 'needsAbstract': [ - 'attributes', - 'children', - 'className', - 'getAttribute', - 'getAttributeNS', - 'getBoundingClientRect', - 'getClientRects', - 'getElementsByClassName', - 'getElementsByTagName', - 'getElementsByTagNameNS', - 'hasAttribute', - 'hasAttributeNS', - 'id', - 'innerHTML', - 'outerHTML', - 'removeAttribute', - 'removeAttributeNS', - 'setAttribute', - 'setAttributeNS', - ] -}, +'Element': {}, 'Event': {}, 'EventListener': { 'nativeType': 'EventListenerBinding::EventListener', }, -'EventTarget': { - 'needsAbstract': ['dispatchEvent'] -}, +'EventTarget': {}, 'FormData': {}, 'HTMLCollection': {}, 'Location': {}, 'MouseEvent': {}, 'Navigator': {}, -'Node': { - 'needsAbstract': [ - 'appendChild', - 'childNodes', - 'cloneNode', - 'compareDocumentPosition', - 'contains', - 'insertBefore', - 'isEqualNode', - 'namespaceURI', - 'nodeName', - 'nodeValue', - 'normalize', - 'removeChild', - 'replaceChild', - 'textContent', - ] -}, - +'Node': {}, 'NodeList': {}, - 'UIEvent': {}, 'ValidityState': {}, 'Window': { 'createGlobal': True, 'outerObjectHook': 'Some(bindings::utils::outerize_global)', - 'needsAbstract': [ - 'console', - 'location', - 'navigator', - 'self', - 'window', - ], }, 'XMLHttpRequest': {}, 'XMLHttpRequestEventTarget': {}, 'XMLHttpRequestUpload': {}, +#FIXME(jdm): This should be 'register': False, but then we don't generate enum types 'TestBinding': {}, } # FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625 -def addHTMLElement(element, concrete=None, needsAbstract=[]): - DOMInterfaces[element] = { - 'nativeType': 'JS<%s>' % element, - 'concreteType': concrete if concrete else element, - 'needsAbstract': needsAbstract - } +def addHTMLElement(element): + DOMInterfaces[element] = {} addHTMLElement('Comment') -addHTMLElement('DocumentFragment', concrete='DocumentFragment', needsAbstract=['children']) +addHTMLElement('DocumentFragment') addHTMLElement('DocumentType') addHTMLElement('Text') addHTMLElement('ProcessingInstruction') @@ -158,12 +77,12 @@ addHTMLElement('HTMLBRElement') addHTMLElement('HTMLCanvasElement') addHTMLElement('HTMLDataElement') addHTMLElement('HTMLDivElement') -addHTMLElement('HTMLDataListElement', needsAbstract=['options']) +addHTMLElement('HTMLDataListElement') addHTMLElement('HTMLDirectoryElement') addHTMLElement('HTMLDListElement') addHTMLElement('HTMLElement') addHTMLElement('HTMLEmbedElement') -addHTMLElement('HTMLFieldSetElement', needsAbstract=['elements']) +addHTMLElement('HTMLFieldSetElement') addHTMLElement('HTMLFontElement') addHTMLElement('HTMLFormElement') addHTMLElement('HTMLFrameElement') @@ -172,8 +91,8 @@ addHTMLElement('HTMLHeadElement') addHTMLElement('HTMLHeadingElement') addHTMLElement('HTMLHtmlElement') addHTMLElement('HTMLHRElement') -addHTMLElement('HTMLIFrameElement', needsAbstract=['sandbox']) -addHTMLElement('HTMLImageElement', needsAbstract=['alt', 'src', 'useMap', 'isMap', 'width', 'height', 'name', 'align', 'hspace', 'vspace', 'longDesc', 'border']) +addHTMLElement('HTMLIFrameElement') +addHTMLElement('HTMLImageElement') addHTMLElement('HTMLInputElement') addHTMLElement('HTMLLabelElement') addHTMLElement('HTMLLegendElement') @@ -195,7 +114,7 @@ addHTMLElement('HTMLParamElement') addHTMLElement('HTMLPreElement') addHTMLElement('HTMLProgressElement') addHTMLElement('HTMLQuoteElement') -addHTMLElement('HTMLScriptElement', needsAbstract=['src']) +addHTMLElement('HTMLScriptElement') addHTMLElement('HTMLSelectElement') addHTMLElement('HTMLSourceElement') addHTMLElement('HTMLSpanElement') diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index cb3fc862c64..55bfa9eac91 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -394,6 +394,9 @@ def typeIsSequenceOrHasSequenceMember(type): type.flatMemberTypes) return False +def typeNeedsRooting(type, descriptorProvider): + return type.isGeckoInterface() and descriptorProvider.getDescriptor(type.name).needsRooting + def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, isDefinitelyObject=False, isMember=False, @@ -481,6 +484,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, if exceptionCode is None: exceptionCode = "return 0;" + needsRooting = typeNeedsRooting(type, descriptorProvider) + def handleOptional(template, declType, isOptional): if isOptional: template = "Some(%s)" % template @@ -489,7 +494,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, else: initialValue = None - return (template, declType, isOptional, initialValue) + return (template, declType, isOptional, initialValue, needsRooting) # Unfortunately, .capitalize() on a string will lowercase things inside the # string, which we do not want. @@ -551,7 +556,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, templateBody += ( "} else {\n" + CGIndenter(onFailureNotAnObject(failureCode)).define() + - "}") + "}\n") if type.nullable(): templateBody = handleDefaultNull(templateBody, "None") else: @@ -601,6 +606,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, failureCode) return handleOptional(template, declType, isOptional) + descriptorType = descriptor.memberType if isMember else descriptor.nativeType + templateBody = "" if descriptor.interface.isConsequential(): raise TypeError("Consequential interface %s being used as an " @@ -616,11 +623,14 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, descriptor, "(${val}).to_object()")) - declType = CGGeneric(descriptor.nativeType) + declType = CGGeneric(descriptorType) if type.nullable(): templateBody = "Some(%s)" % templateBody declType = CGWrapper(declType, pre="Option<", post=">") + if isMember: + templateBody += ".root()" + templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject, type, failureCode) @@ -745,7 +755,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, "} else {\n" " ${declName} = NULL;\n" "}" % haveCallable, - CGGeneric("JSObject*"), isOptional, None) + CGGeneric("JSObject*"), isOptional, None, needsRooting) if type.isAny(): assert not isEnforceRange and not isClamp @@ -789,7 +799,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, assert not isOptional # This one only happens for return values, and its easy: Just # ignore the jsval. - return ("", None, False, None) + return ("", None, False, None, False) if not type.isPrimitive(): raise TypeError("Need conversion for argument type '%s'" % str(type)) @@ -842,7 +852,7 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements, replace ${argc} and ${index}, where ${index} is the index of this argument (0-based) and ${argc} is the total number of arguments. """ - (templateBody, declType, dealWithOptional, initialValue) = templateTuple + (templateBody, declType, dealWithOptional, initialValue, needsRooting) = templateTuple if dealWithOptional and argcAndIndex is None: raise TypeError("Have to deal with optional things, but don't know how") @@ -888,6 +898,12 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements, # Add an empty CGGeneric to get an extra newline after the argument # conversion. result.append(CGGeneric("")) + + if needsRooting: + rootBody = "let ${declName} = ${declName}.root();" + result.append(CGGeneric(string.Template(rootBody).substitute(replacements))) + result.append(CGGeneric("")) + return result; def convertConstIDLValueToJSVal(value): @@ -985,6 +1001,13 @@ def typeNeedsCx(type, retVal=False): return True return type.isCallback() or type.isAny() or type.isObject() +def typeRetValNeedsRooting(type): + if type is None: + return False + if type.nullable(): + type = type.inner + return type.isGeckoInterface() and not type.isCallback() + def memberIsCreator(member): return member.getExtendedAttribute("Creator") is not None @@ -1016,7 +1039,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType.isGeckoInterface(): descriptor = descriptorProvider.getDescriptor( returnType.unroll().inner.identifier.name) - result = CGGeneric(descriptor.nativeType) + result = CGGeneric(descriptor.returnType) if returnType.nullable(): result = CGWrapper(result, pre="Option<", post=">") return result @@ -1365,7 +1388,7 @@ class CGImports(CGWrapper): """ Generates the appropriate import/use statements. """ - def __init__(self, child, imports): + def __init__(self, child, descriptors, imports): """ Adds a set of imports. """ @@ -1385,6 +1408,10 @@ class CGImports(CGWrapper): 'dead_code', ] + for d in descriptors: + name = d.interface.identifier.name + imports.append('dom::%s::%sMethods' % (name.lower(), name)) + statements = ['#![allow(%s)]' % ','.join(ignored_warnings)] statements.extend('use %s;' % i for i in sorted(imports)) @@ -1763,7 +1790,7 @@ class CGAbstractMethod(CGThing): def _returnType(self): return (" -> %s" % self.returnType) if self.returnType != "void" else "" def _unsafe_open(self): - return "\n unsafe {" if self.unsafe else "" + return "\n unsafe {\n" if self.unsafe else "" def _unsafe_close(self): return "\n }\n" if self.unsafe else "" @@ -1783,7 +1810,7 @@ def CreateBindingJSObject(descriptor, parent=None): if descriptor.proxy: assert not descriptor.createGlobal handler = """ - let js_info = aScope.get().page().js_info(); + let js_info = aScope.deref().page().js_info(); let handler = js_info.get_ref().dom_static.proxy_handlers.deref().get(&(PrototypeList::id::%s as uint)); """ % descriptor.name create += handler + """ let obj = NewProxyObject(aCx, *handler, @@ -1809,7 +1836,7 @@ class CGWrapMethod(CGAbstractMethod): def __init__(self, descriptor): assert descriptor.interface.hasInterfacePrototypeObject() if not descriptor.createGlobal: - args = [Argument('*JSContext', 'aCx'), Argument('&JS<Window>', 'aScope'), + args = [Argument('*JSContext', 'aCx'), Argument('&JSRef<Window>', 'aScope'), Argument("~" + descriptor.concreteType, 'aObject', mutable=True)] else: args = [Argument('*JSContext', 'aCx'), @@ -2210,6 +2237,9 @@ class CGCallGenerator(CGThing): self.cgRoot.append(CGGeneric("}")) self.cgRoot.append(CGGeneric("result = result_fallible.unwrap();")) + if typeRetValNeedsRooting(returnType): + self.cgRoot.append(CGGeneric("let result = result.root();")) + def define(self): return self.cgRoot.define() @@ -2277,7 +2307,12 @@ class CGPerSignatureCall(CGThing): def getArgc(self): return "argc" def getArguments(self): - return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)] + def process(arg, i): + argVal = "arg" + str(i) + if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback(): + argVal += ".root_ref()" + return argVal + return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)] def isFallible(self): return not 'infallible' in self.extendedAttributes @@ -2447,17 +2482,10 @@ class CGSpecializedMethod(CGAbstractExternMethod): def definition_body(self): name = self.method.identifier.name - nativeName = MakeNativeName(name) - extraPre = '' - argsPre = [] - if name in self.descriptor.needsAbstract: - abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] - return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(), + return CGWrapper(CGMethodCall([], MakeNativeName(name), self.method.isStatic(), self.descriptor, self.method), - pre=extraPre + - " let this = &mut *this;\n").define() + pre=" let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n").define() class CGGenericGetter(CGAbstractBindingMethod): """ @@ -2480,10 +2508,8 @@ class CGGenericGetter(CGAbstractBindingMethod): def generate_code(self): return CGIndenter(CGGeneric( - "return with_gc_disabled(cx, || {\n" - " let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" - " CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp)\n" - "});\n")) + "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" + "return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp);\n")) class CGSpecializedGetter(CGAbstractExternMethod): """ @@ -2502,21 +2528,15 @@ class CGSpecializedGetter(CGAbstractExternMethod): def definition_body(self): name = self.attr.identifier.name nativeName = MakeNativeName(name) - extraPre = '' - argsPre = [] infallible = ('infallible' in self.descriptor.getExtendedAttributes(self.attr, getter=True)) - if name in self.descriptor.needsAbstract: - abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] if self.attr.type.nullable() or not infallible: nativeName = "Get" + nativeName - return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName, + return CGWrapper(CGIndenter(CGGetterCall([], self.attr.type, nativeName, self.descriptor, self.attr)), - pre=extraPre + - " let this = &mut *this;\n").define() + pre=" let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n").define() class CGGenericSetter(CGAbstractBindingMethod): """ @@ -2541,10 +2561,7 @@ class CGGenericSetter(CGAbstractBindingMethod): "let undef = UndefinedValue();\n" "let argv: *JSVal = if argc != 0 { JS_ARGV(cx, vp as *JSVal) } else { &undef as *JSVal };\n" "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp as *JSVal));\n" - "let ok = with_gc_disabled(cx, || {\n" - " CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv)\n" - "});\n" - "if ok == 0 {\n" + "if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv) == 0 {\n" " return 0;\n" "}\n" "*vp = UndefinedValue();\n" @@ -2566,17 +2583,11 @@ class CGSpecializedSetter(CGAbstractExternMethod): def definition_body(self): name = self.attr.identifier.name - nativeName = "Set" + MakeNativeName(name) - argsPre = [] - extraPre = '' - if name in self.descriptor.needsAbstract: - abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] - return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName, + return CGWrapper(CGIndenter(CGSetterCall([], self.attr.type, + "Set" + MakeNativeName(name), self.descriptor, self.attr)), - pre=extraPre + - " let this = &mut *this;\n").define() + pre=" let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n").define() class CGMemberJITInfo(CGThing): @@ -2744,7 +2755,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider): name = type.name typeName = "/*" + type.name + "*/" - (template, _, _, _) = getJSToNativeConversionTemplate( + (template, _, _, _, _) = getJSToNativeConversionTemplate( type, descriptorProvider, failureCode="return Ok(None);", exceptionCode='return Err(());', isDefinitelyObject=True, isOptional=False) @@ -3411,7 +3422,12 @@ class CGProxySpecialOperation(CGPerSignatureCall): self.cgRoot.prepend(CGGeneric("let mut found = false;")) def getArguments(self): - args = [(a, a.identifier.name) for a in self.arguments] + def process(arg): + argVal = arg.identifier.name + if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback(): + argVal += ".root_ref()" + return argVal + args = [(a, process(a)) for a in self.arguments] if self.idlNode.isGetter(): args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean], self.idlNode), @@ -3461,14 +3477,14 @@ class CGProxyNamedSetter(CGProxySpecialOperation): class CGProxyUnwrap(CGAbstractMethod): def __init__(self, descriptor): args = [Argument('*JSObject', 'obj')] - CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*' + descriptor.concreteType, args, alwaysInline=True) + CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*mut ' + descriptor.concreteType, args, alwaysInline=True) def definition_body(self): return """ /*if (xpc::WrapperFactory::IsXrayWrapper(obj)) { obj = js::UnwrapObject(obj); }*/ //MOZ_ASSERT(IsProxy(obj)); - let box_: *%s = cast::transmute(GetProxyPrivate(obj).to_private()); + let box_: *mut %s = cast::transmute(GetProxyPrivate(obj).to_private()); return box_;""" % (self.descriptor.concreteType) class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): @@ -3493,9 +3509,11 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor} get = ("if index.is_some() {\n" + " let index = index.unwrap();\n" + - " let this: *%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" + - "}\n") % (self.descriptor.concreteType) + "}\n") if indexedSetter or self.descriptor.operations['NamedSetter']: setOrIndexedGet += "if set != 0 {\n" @@ -3538,9 +3556,11 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): namedGet = ("\n" + "if set == 0 && RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" + " let name = Some(jsid_to_str(cx, id));\n" + - " let this: *%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" + - "}\n") % (self.descriptor.concreteType) + "}\n") else: namedGet = "" @@ -3581,10 +3601,12 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): set += ("let index = GetArrayIndexFromId(cx, id);\n" + "if index.is_some() {\n" + " let index = index.unwrap();\n" + - " let this: *mut %s = UnwrapProxy(proxy) as *mut %s;\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() + " return 1;\n" + - "}\n") % (self.descriptor.concreteType, self.descriptor.concreteType) + "}\n") elif self.descriptor.operations['IndexedGetter']: set += ("if GetArrayIndexFromId(cx, id).is_some() {\n" + " return 0;\n" + @@ -3597,20 +3619,24 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): raise TypeError("Can't handle creator that's different from the setter") set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" + " let name = Some(jsid_to_str(cx, id));\n" + - " let this: *%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" + - "}\n") % (self.descriptor.concreteType) + "}\n") elif self.descriptor.operations['NamedGetter']: set += ("if RUST_JSID_IS_STRING(id) {\n" + " let name = Some(jsid_to_str(cx, id));\n" + - " let this: %%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + " if (found) {\n" " return 0;\n" + " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" + " }\n" + " return 1;\n" - "}\n") % (self.descriptor.concreteType, self.descriptor.name) + "}\n") % (self.descriptor.name) return set + """return proxyhandler::defineProperty_(%s);""" % ", ".join(a.name for a in self.args) def definition_body(self): @@ -3628,11 +3654,13 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): indexed = ("let index = GetArrayIndexFromId(cx, id);\n" + "if index.is_some() {\n" + " let index = index.unwrap();\n" + - " let this: *%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" + " *bp = found as JSBool;\n" + " return 1;\n" + - "}\n\n") % (self.descriptor.concreteType) + "}\n\n") else: indexed = "" @@ -3640,12 +3668,14 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): if namedGetter: named = ("if RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" + " let name = Some(jsid_to_str(cx, id));\n" + - " let this: *%s = UnwrapProxy(proxy);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" + " *bp = found as JSBool;\n" " return 1;\n" "}\n" + - "\n") % (self.descriptor.concreteType) + "\n") else: named = "" @@ -3693,6 +3723,8 @@ if expando.is_not_null() { "if index.is_some() {\n" + " let index = index.unwrap();\n" + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) getIndexedOrExpando += """ // Even if we don't have this index, we don't forward the @@ -3709,6 +3741,8 @@ if expando.is_not_null() { getNamed = ("if (JSID_IS_STRING(id)) {\n" + " let name = Some(jsid_to_str(cx, id));\n" + " let this = UnwrapProxy(proxy);\n" + + " let this = JS::from_raw(this);\n" + + " let mut this = this.root();\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "}\n") % (self.descriptor.concreteType) else: @@ -3825,11 +3859,11 @@ class CGClassConstructHook(CGAbstractExternMethod): def generate_code(self): preamble = """ - let global = global_object_for_js_object(JS_CALLEE(cx, &*vp).to_object()); - let obj = global.reflector().get_jsobject(); + let global = global_object_for_js_object(JS_CALLEE(cx, &*vp).to_object()).root(); + let obj = global.deref().reflector().get_jsobject(); """ nativeName = MakeNativeName(self._ctor.identifier.name) - callGenerator = CGMethodCall(["&global"], nativeName, True, + callGenerator = CGMethodCall(["&global.root_ref()"], nativeName, True, self.descriptor, self._ctor) return preamble + callGenerator.define(); @@ -4030,7 +4064,7 @@ class CGDictionary(CGThing): def struct(self): d = self.dictionary if d.parent: - inheritance = " pub parent: %s::%s,\n" % (self.makeModuleName(d.parent), + inheritance = " pub parent: %s::%s<'a, 'b>,\n" % (self.makeModuleName(d.parent), self.makeClassName(d.parent)) else: inheritance = "" @@ -4039,7 +4073,7 @@ class CGDictionary(CGThing): for m in self.memberInfo] return (string.Template( - "pub struct ${selfName} {\n" + + "pub struct ${selfName}<'a, 'b> {\n" + "${inheritance}" + "\n".join(memberDecls) + "\n" + "}").substitute( { "selfName": self.makeClassName(d), @@ -4065,7 +4099,7 @@ class CGDictionary(CGThing): memberInits = CGList([memberInit(m) for m in self.memberInfo]) return string.Template( - "impl ${selfName} {\n" + "impl<'a, 'b> ${selfName}<'a, 'b> {\n" " pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n" " let object = if val.is_null_or_undefined() {\n" " ptr::null()\n" @@ -4104,14 +4138,14 @@ class CGDictionary(CGThing): def getMemberType(self, memberInfo): (member, (templateBody, declType, - dealWithOptional, initialValue)) = memberInfo + dealWithOptional, initialValue, _)) = memberInfo if dealWithOptional: declType = CGWrapper(declType, pre="Optional< ", post=" >") return declType.define() def getMemberConversion(self, memberInfo): (member, (templateBody, declType, - dealWithOptional, initialValue)) = memberInfo + dealWithOptional, initialValue, _)) = memberInfo replacements = { "val": "value.unwrap()" } if member.defaultValue: replacements["haveValue"] = "value.is_some()" @@ -4238,7 +4272,7 @@ class CGBindingRoot(CGThing): # Add imports #XXXjdm This should only import the namespace for the current binding, # not every binding ever. - curr = CGImports(curr, [ + curr = CGImports(curr, descriptors, [ 'js', 'js::{JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}', 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}', @@ -4266,7 +4300,9 @@ class CGBindingRoot(CGThing): 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}', 'dom::types::*', 'dom::bindings', - 'dom::bindings::js::JS', + 'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary}', + 'dom::bindings::js::{OptionalRootable, OptionalRootedRootable, ResultRootable}', + 'dom::bindings::js::{OptionalRootedReference, OptionalOptionalRootedRootable}', 'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}', 'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}', 'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}', @@ -4279,8 +4315,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{Reflectable}', 'dom::bindings::utils::{squirrel_away_unique}', 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', - 'dom::bindings::utils::{VoidVal, with_gc_disabled}', - 'dom::bindings::utils::{with_gc_enabled}', + 'dom::bindings::utils::VoidVal', 'dom::bindings::utils::get_dictionary_property', 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface}', @@ -4549,7 +4584,7 @@ class CGNativeMember(ClassMethod): else: typeDecl = "%s" descriptor = self.descriptorProvider.getDescriptor(iface.identifier.name) - return (typeDecl % descriptor.nativeType, + return (typeDecl % descriptor.argumentType, False, False) if type.isSpiderMonkeyInterface(): @@ -5057,11 +5092,8 @@ class CallbackMethod(CallbackMember): replacements["argc"] = "0" return string.Template("${getCallable}" "let ok = unsafe {\n" - " //JS_AllowGC(cx); // It's unsafe to enable GC at arbitrary points during Rust execution; leave it disabled\n" - " let ok = JS_CallFunctionValue(cx, ${thisObj}, callable,\n" - " ${argc}, ${argv}, &rval);\n" - " //JS_InhibitGC(cx);\n" - " ok\n" + " JS_CallFunctionValue(cx, ${thisObj}, callable,\n" + " ${argc}, ${argv}, &rval)\n" "};\n" "if ok == 0 {\n" " return${errorReturn};\n" @@ -5207,9 +5239,9 @@ class GlobalGenRoots(): @staticmethod def RegisterBindings(config): # TODO - Generate the methods we want - return CGImports(CGRegisterProtos(config), [ + return CGImports(CGRegisterProtos(config), [], [ 'dom::bindings::codegen', - 'dom::bindings::js::JS', + 'dom::bindings::js::{JS, JSRef}', 'dom::window::Window', 'script_task::JSPageInfo', ]) @@ -5241,8 +5273,9 @@ class GlobalGenRoots(): descriptors = config.getDescriptors(register=True, hasInterfaceObject=True) allprotos = [CGGeneric("#![allow(unused_imports)]\n"), CGGeneric("use dom::types::*;\n"), - CGGeneric("use dom::bindings::js::JS;\n"), + CGGeneric("use dom::bindings::js::{JS, JSRef, Temporary};\n"), CGGeneric("use dom::bindings::trace::JSTraceable;\n"), + CGGeneric("use dom::bindings::utils::Reflectable;\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"), CGGeneric("use js::jsapi::JSTracer;\n\n")] for descriptor in descriptors: @@ -5269,22 +5302,34 @@ class GlobalGenRoots(): cast = [CGGeneric(string.Template('''pub trait ${castTraitName} { #[inline(always)] - fn from<T: ${fromBound}>(derived: &JS<T>) -> JS<Self> { - unsafe { derived.clone().transmute() } + fn to_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, Self>> { + match base.deref().${checkFn}() { + true => unsafe { Some(base.transmute()) }, + false => None + } } #[inline(always)] - fn to<T: ${toBound}>(base: &JS<T>) -> Option<JS<Self>> { - match base.get().${checkFn}() { - true => unsafe { Some(base.clone().transmute()) }, + fn to_mut_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a mut JSRef<'b, T>) -> Option<&'a mut JSRef<'b, Self>> { + match base.deref().${checkFn}() { + true => unsafe { Some(base.transmute_mut()) }, false => None } } #[inline(always)] - unsafe fn to_unchecked<T: ${toBound}>(base: &JS<T>) -> JS<Self> { - assert!(base.get().${checkFn}()); - base.clone().transmute() + fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> { + unsafe { derived.transmute() } + } + + #[inline(always)] + fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> { + unsafe { derived.transmute_mut() } + } + + #[inline(always)] + fn from_unrooted<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<Self> { + unsafe { derived.transmute() } } } ''').substitute({'checkFn': 'is_' + name.lower(), @@ -5313,7 +5358,7 @@ class GlobalGenRoots(): curr = UnionTypes(config.getDescriptors()) - curr = CGImports(curr, [ + curr = CGImports(curr, [], [ 'dom::bindings::utils::unwrap_jsmanaged', 'dom::bindings::codegen::PrototypeList', 'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}', diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py index a1ccb460ee2..1272867f542 100644 --- a/src/components/script/dom/bindings/codegen/Configuration.py +++ b/src/components/script/dom/bindings/codegen/Configuration.py @@ -128,14 +128,19 @@ class Descriptor(DescriptorProvider): # Read the desc, and fill in the relevant defaults. ifaceName = self.interface.identifier.name + + # Callback types do not use JS smart pointers, so we should not use the + # built-in rooting mechanisms for them. if self.interface.isCallback(): - nativeTypeDefault = "nsIDOM" + ifaceName + self.needsRooting = False else: - nativeTypeDefault = 'JS<%s>' % ifaceName + self.needsRooting = True - self.nativeType = desc.get('nativeType', nativeTypeDefault) + self.returnType = "Temporary<%s>" % ifaceName + self.argumentType = "JSRef<%s>" % ifaceName + self.memberType = "Root<'a, 'b, %s>" % ifaceName + self.nativeType = desc.get('nativeType', 'JS<%s>' % ifaceName) self.concreteType = desc.get('concreteType', ifaceName) - self.needsAbstract = desc.get('needsAbstract', []) self.createGlobal = desc.get('createGlobal', False) self.register = desc.get('register', True) self.outerObjectHook = desc.get('outerObjectHook', 'None') diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index 6721f3f5dde..02d6983cf3b 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -2,9 +2,9 @@ * 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::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Root}; use dom::bindings::str::ByteString; -use dom::bindings::utils::Reflectable; +use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::utils::jsstring_to_str; use dom::bindings::utils::unwrap_jsmanaged; use servo_util::str::DOMString; @@ -293,9 +293,9 @@ impl FromJSValConvertible<()> for ByteString { } } -impl<T: Reflectable> ToJSValConvertible for JS<T> { +impl ToJSValConvertible for Reflector { fn to_jsval(&self, cx: *JSContext) -> JSVal { - let obj = self.reflector().get_jsobject(); + let obj = self.get_jsobject(); assert!(obj.is_not_null()); let mut value = ObjectValue(unsafe { &*obj }); if unsafe { JS_WrapValue(cx, &mut value as *mut JSVal as *JSVal) } == 0 { @@ -316,6 +316,18 @@ impl<T: Reflectable+IDLInterface> FromJSValConvertible<()> for JS<T> { } } +impl<'a, 'b, T: Reflectable> ToJSValConvertible for Root<'a, 'b, T> { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + self.reflector().to_jsval(cx) + } +} + +impl<'a, T: Reflectable> ToJSValConvertible for JSRef<'a, T> { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + self.reflector().to_jsval(cx) + } +} + impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> { fn to_jsval(&self, cx: *JSContext) -> JSVal { match self { diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 10aec5424bc..da84c85eeb7 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -2,14 +2,115 @@ * 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::bindings::utils::{Reflector, Reflectable}; -use dom::window::Window; -use js::jsapi::JSContext; +/// The DOM is made up of Rust types whose lifetime is entirely controlled by the whims of +/// the SpiderMonkey garbage collector. The types in this module are designed to ensure +/// that any interactions with said Rust types only occur on values that will remain alive +/// the entire time. +/// +/// Here is a brief overview of the important types: +/// - JSRef<T>: a freely-copyable reference to a rooted value. +/// - JS<T>: a pointer to JS-owned memory that can automatically be traced by the GC when +/// encountered as a field of a Rust structure. +/// - Temporary<T>: a value that will remain rooted for the duration of its lifetime. +/// +/// The rule of thumb is as follows: +/// - All methods return Temporary<T>, to ensure the value remains alive until it is stored +/// somewhere that is reachable by the GC. +/// - All functions take &JSRef<T> arguments, to ensure that they will remain uncollected for +/// the duration of their usage. +/// - All types contain JS<T> fields and derive the Encodable trait, to ensure that they are +/// transitively marked as reachable by the GC if the enclosing value is reachable. +/// - All methods for type T are implemented for JSRef<T>, to ensure that the self value +/// will not be collected for the duration of the method call. +/// +/// Both Temporary<T> and JS<T> do not allow access to their inner value without explicitly +/// creating a stack-based root via the `root` method. This returns a Root<T>, which causes +/// the JS-owned value to be uncollectable for the duration of the Root type's lifetime. +/// A JSRef<T> can be obtained from a Root<T> either by dereferencing the Root<T> (`*rooted`) +/// or explicitly calling the `root_ref` method. These JSRef<T> values are not allowed to +/// outlive their originating Root<T>, to ensure that all interactions with the enclosed value +/// only occur when said value is uncollectable, and will cause static lifetime errors if +/// misused. +/// +/// Other miscellaneous helper traits: +/// - OptionalRootable and OptionalRootedRootable: make rooting Option values easy via a `root` method +/// - ResultRootable: make rooting successful Result values easy +/// - TemporaryPushable: allows mutating vectors of JS<T> with new elements of JSRef/Temporary +/// - OptionalSettable: allows assigning Option values of JSRef/Temporary to fields of Option<JS<T>> +/// - RootedReference: makes obtaining an Option<JSRef<T>> from an Option<Root<T>> easy + +use dom::bindings::utils::{Reflector, Reflectable, cx_for_dom_object}; +use dom::node::Node; +use js::jsapi::{JSObject, JS_AddObjectRoot, JS_RemoveObjectRoot}; use layout_interface::TrustedNodeAddress; +use script_task::StackRoots; use std::cast; use std::cell::RefCell; +use std::local_data; + +/// A type that represents a JS-owned value that is rooted for the lifetime of this value. +/// Importantly, it requires explicit rooting in order to interact with the inner value. +/// Can be assigned into JS-owned member fields (ie. JS<T> types) safely via the +/// `JS<T>::assign` method or `OptionalSettable::assign` (for Option<JS<T>> fields). +pub struct Temporary<T> { + inner: JS<T>, +} + +impl<T> Eq for Temporary<T> { + fn eq(&self, other: &Temporary<T>) -> bool { + self.inner == other.inner + } +} + +#[unsafe_destructor] +impl<T: Reflectable> Drop for Temporary<T> { + fn drop(&mut self) { + let cx = cx_for_dom_object(&self.inner); + unsafe { + JS_RemoveObjectRoot(cx, self.inner.reflector().rootable()); + } + } +} + +impl<T: Reflectable> Temporary<T> { + /// Create a new Temporary value from a JS-owned value. + pub fn new(inner: JS<T>) -> Temporary<T> { + let cx = cx_for_dom_object(&inner); + unsafe { + JS_AddObjectRoot(cx, inner.reflector().rootable()); + } + Temporary { + inner: inner, + } + } + + /// Create a new Temporary value from a rooted value. + pub fn from_rooted<'a>(root: &JSRef<'a, T>) -> Temporary<T> { + Temporary::new(root.unrooted()) + } + + /// Create a stack-bounded root for this value. + pub fn root<'a, 'b>(self) -> Root<'a, 'b, T> { + local_data::get(StackRoots, |opt| { + let collection = opt.unwrap(); + unsafe { + (**collection).new_root(&self.inner) + } + }) + } + + unsafe fn inner(&self) -> JS<T> { + self.inner.clone() + } + + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute<To>(self) -> Temporary<To> { + cast::transmute(self) + } +} +/// A rooted, JS-owned value. Must only be used as a field in other JS-owned types. pub struct JS<T> { ptr: RefCell<*mut T> } @@ -29,13 +130,18 @@ impl <T> Clone for JS<T> { } } -impl<T: Reflectable> JS<T> { - pub fn new(obj: ~T, - window: &JS<Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> { - wrap_fn(window.get().get_cx(), window, obj) +impl JS<Node> { + /// Create a new JS-owned value wrapped from an address known to be a Node pointer. + pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<Node> { + let TrustedNodeAddress(addr) = inner; + JS { + ptr: RefCell::new(addr as *mut Node) + } } +} +impl<T: Reflectable> JS<T> { + /// Create a new JS-owned value wrapped from a raw Rust pointer. pub unsafe fn from_raw(raw: *mut T) -> JS<T> { JS { ptr: RefCell::new(raw) @@ -43,45 +149,47 @@ impl<T: Reflectable> JS<T> { } - pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> { - let TrustedNodeAddress(addr) = inner; - JS { - ptr: RefCell::new(addr as *mut T) - } + /// Root this JS-owned value to prevent its collection as garbage. + pub fn root<'a, 'b>(&self) -> Root<'a, 'b, T> { + local_data::get(StackRoots, |opt| { + let collection = opt.unwrap(); + unsafe { + (**collection).new_root(self) + } + }) } } +//XXXjdm This is disappointing. This only gets called from trace hooks, in theory, +// so it's safe to assume that self is rooted and thereby safe to access. impl<T: Reflectable> Reflectable for JS<T> { fn reflector<'a>(&'a self) -> &'a Reflector { - self.get().reflector() - } - - fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.get_mut().mut_reflector() - } -} - -impl<T> JS<T> { - pub fn get<'a>(&'a self) -> &'a T { - let borrowed = self.ptr.borrow(); unsafe { - &**borrowed + (*self.unsafe_get()).reflector() } } - pub fn get_mut<'a>(&'a mut self) -> &'a mut T { - let mut borrowed = self.ptr.borrow_mut(); + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { unsafe { - &mut **borrowed + (*self.unsafe_get()).mut_reflector() } } +} +impl<T: Reflectable> JS<T> { /// Returns an unsafe pointer to the interior of this JS object without touching the borrow /// flags. This is the only method that be safely accessed from layout. (The fact that this /// is unsafe is what necessitates the layout wrappers.) pub unsafe fn unsafe_get(&self) -> *mut T { cast::transmute_copy(&self.ptr) } + + /// Store an unrooted value in this field. This is safe under the assumption that JS<T> + /// values are only used as fields in DOM types that are reachable in the GC graph, + /// so this unrooted value becomes transitively rooted for the lifetime of its new owner. + pub fn assign(&mut self, val: Temporary<T>) { + *self = unsafe { val.inner() }; + } } impl<From, To> JS<From> { @@ -94,3 +202,304 @@ impl<From, To> JS<From> { cast::transmute_copy(self) } } + + +/// Get an Option<JSRef<T>> out of an Option<Root<T>> +pub trait RootedReference<T> { + fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>>; +} + +impl<'a, 'b, T: Reflectable> RootedReference<T> for Option<Root<'a, 'b, T>> { + fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>> { + self.as_ref().map(|root| root.root_ref()) + } +} + +/// Get an Option<Option<JSRef<T>>> out of an Option<Option<Root<T>>> +pub trait OptionalRootedReference<T> { + fn root_ref<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>; +} + +impl<'a, 'b, T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<'a, 'b, T>>> { + fn root_ref<'a>(&'a self) -> Option<Option<JSRef<'a, T>>> { + self.as_ref().map(|inner| inner.root_ref()) + } +} + +/// Trait that allows extracting a JS<T> value from a variety of rooting-related containers, +/// which in general is an unsafe operation since they can outlive the rooted lifetime of the +/// original value. +/*definitely not public*/ trait Assignable<T> { + unsafe fn get_js(&self) -> JS<T>; +} + +impl<T> Assignable<T> for JS<T> { + unsafe fn get_js(&self) -> JS<T> { + self.clone() + } +} + +impl<'a, T> Assignable<T> for JSRef<'a, T> { + unsafe fn get_js(&self) -> JS<T> { + self.unrooted() + } +} + +impl<T: Reflectable> Assignable<T> for Temporary<T> { + unsafe fn get_js(&self) -> JS<T> { + self.inner() + } +} + +/// Assign an optional rootable value (either of JS<T> or Temporary<T>) to an optional +/// field of a DOM type (ie. Option<JS<T>>) +pub trait OptionalSettable<T> { + fn assign(&mut self, val: Option<T>); +} + +impl<T: Assignable<U>, U: Reflectable> OptionalSettable<T> for Option<JS<U>> { + fn assign(&mut self, val: Option<T>) { + *self = val.map(|val| unsafe { val.get_js() }); + } +} + +/// Root a rootable Option type (used for Option<Temporary<T>>) +pub trait OptionalRootable<T> { + fn root<'a, 'b>(self) -> Option<Root<'a, 'b, T>>; +} + +impl<T: Reflectable> OptionalRootable<T> for Option<Temporary<T>> { + fn root<'a, 'b>(self) -> Option<Root<'a, 'b, T>> { + self.map(|inner| inner.root()) + } +} + +/// Return an unrooted type for storing in optional DOM fields +pub trait OptionalUnrootable<T> { + fn unrooted(&self) -> Option<JS<T>>; +} + +impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> { + fn unrooted(&self) -> Option<JS<T>> { + self.as_ref().map(|inner| inner.unrooted()) + } +} + +/// Root a rootable Option type (used for Option<JS<T>>) +pub trait OptionalRootedRootable<T> { + fn root<'a, 'b>(&self) -> Option<Root<'a, 'b, T>>; +} + +impl<T: Reflectable> OptionalRootedRootable<T> for Option<JS<T>> { + fn root<'a, 'b>(&self) -> Option<Root<'a, 'b, T>> { + self.as_ref().map(|inner| inner.root()) + } +} + +/// Root a rootable Option<Option> type (used for Option<Option<JS<T>>>) +pub trait OptionalOptionalRootedRootable<T> { + fn root<'a, 'b>(&self) -> Option<Option<Root<'a, 'b, T>>>; +} + +impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<JS<T>>> { + fn root<'a, 'b>(&self) -> Option<Option<Root<'a, 'b, T>>> { + self.as_ref().map(|inner| inner.root()) + } +} + + +/// Root a rootable Result type (any of Temporary<T> or JS<T>) +pub trait ResultRootable<T,U> { + fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U>; +} + +impl<T: Reflectable, U> ResultRootable<T, U> for Result<Temporary<T>, U> { + fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U> { + self.map(|inner| inner.root()) + } +} + +impl<T: Reflectable, U> ResultRootable<T, U> for Result<JS<T>, U> { + fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U> { + self.map(|inner| inner.root()) + } +} + +/// Provides a facility to push unrooted values onto lists of rooted values. This is safe +/// under the assumption that said lists are reachable via the GC graph, and therefore the +/// new values are transitively rooted for the lifetime of their new owner. +pub trait TemporaryPushable<T> { + fn push_unrooted(&mut self, val: &T); + fn insert_unrooted(&mut self, index: uint, val: &T); +} + +impl<T: Assignable<U>, U: Reflectable> TemporaryPushable<T> for Vec<JS<U>> { + fn push_unrooted(&mut self, val: &T) { + self.push(unsafe { val.get_js() }); + } + + fn insert_unrooted(&mut self, index: uint, val: &T) { + self.insert(index, unsafe { val.get_js() }); + } +} + +/// An opaque, LIFO rooting mechanism. +pub struct RootCollection { + roots: RefCell<Vec<*JSObject>>, +} + +impl RootCollection { + /// Create an empty collection of roots + pub fn new() -> RootCollection { + RootCollection { + roots: RefCell::new(vec!()), + } + } + + /// Create a new stack-bounded root that will not outlive this collection + fn new_root<'a, 'b, T: Reflectable>(&'a self, unrooted: &JS<T>) -> Root<'a, 'b, T> { + Root::new(self, unrooted) + } + + /// Track a stack-based root to ensure LIFO root ordering + fn root<'a, 'b, T: Reflectable>(&self, untracked: &Root<'a, 'b, T>) { + let mut roots = self.roots.borrow_mut(); + roots.push(untracked.js_ptr); + debug!(" rooting {:?}", untracked.js_ptr); + } + + /// Stop tracking a stack-based root, asserting if LIFO root ordering has been violated + fn unroot<'a, 'b, T: Reflectable>(&self, rooted: &Root<'a, 'b, T>) { + let mut roots = self.roots.borrow_mut(); + debug!("unrooting {:?} (expecting {:?}", roots.last().unwrap(), rooted.js_ptr); + assert!(*roots.last().unwrap() == rooted.js_ptr); + roots.pop().unwrap(); + } +} + +/// A rooted JS value. The JS value is pinned for the duration of this object's lifetime; +/// roots are additive, so this object's destruction will not invalidate other roots +/// for the same JS value. Roots cannot outlive the associated RootCollection object. +/// Attempts to transfer ownership of a Root via moving will trigger dynamic unrooting +/// failures due to incorrect ordering. +pub struct Root<'a, 'b, T> { + /// List that ensures correct dynamic root ordering + root_list: &'a RootCollection, + /// Reference to rooted value that must not outlive this container + jsref: JSRef<'b, T>, + /// Pointer to underlying Rust data + ptr: RefCell<*mut T>, + /// On-stack JS pointer to assuage conservative stack scanner + js_ptr: *JSObject, +} + +impl<'a, 'b, T: Reflectable> Root<'a, 'b, T> { + /// Create a new stack-bounded root for the provided JS-owned value. + /// It cannot not outlive its associated RootCollection, and it contains a JSRef + /// which cannot outlive this new Root. + fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, 'b, T> { + let root = Root { + root_list: roots, + jsref: JSRef { + ptr: unrooted.ptr.clone(), + chain: unsafe { cast::transmute_region(&()) }, + }, + ptr: unrooted.ptr.clone(), + js_ptr: unrooted.reflector().get_jsobject(), + }; + roots.root(&root); + root + } + + /// Obtain a safe reference to the wrapped JS owned-value that cannot outlive + /// the lifetime of this root. + pub fn root_ref<'b>(&'b self) -> JSRef<'b,T> { + self.jsref.clone() + } +} + +#[unsafe_destructor] +impl<'a, 'b, T: Reflectable> Drop for Root<'a, 'b, T> { + fn drop(&mut self) { + self.root_list.unroot(self); + } +} + +impl<'a, 'b, T: Reflectable> Deref<JSRef<'b, T>> for Root<'a, 'b, T> { + fn deref<'c>(&'c self) -> &'c JSRef<'b, T> { + &self.jsref + } +} + +impl<'a, 'b, T: Reflectable> DerefMut<JSRef<'b, T>> for Root<'a, 'b, T> { + fn deref_mut<'c>(&'c mut self) -> &'c mut JSRef<'b, T> { + &mut self.jsref + } +} + +impl<'a, T: Reflectable> Deref<T> for JSRef<'a, T> { + fn deref<'b>(&'b self) -> &'b T { + let borrow = self.ptr.borrow(); + unsafe { + &**borrow + } + } +} + +impl<'a, T: Reflectable> DerefMut<T> for JSRef<'a, T> { + fn deref_mut<'b>(&'b mut self) -> &'b mut T { + let mut borrowed = self.ptr.borrow_mut(); + unsafe { + &mut **borrowed + } + } +} + +/// Encapsulates a reference to something that is guaranteed to be alive. This is freely copyable. +pub struct JSRef<'a, T> { + ptr: RefCell<*mut T>, + chain: &'a (), +} + +impl<'a, T> Clone for JSRef<'a, T> { + fn clone(&self) -> JSRef<'a, T> { + JSRef { + ptr: self.ptr.clone(), + chain: self.chain + } + } +} + +impl<'a, T> Eq for JSRef<'a, T> { + fn eq(&self, other: &JSRef<T>) -> bool { + self.ptr == other.ptr + } +} + +impl<'a,T> JSRef<'a,T> { + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute<'b, To>(&'b self) -> &'b JSRef<'a, To> { + cast::transmute(self) + } + + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute_mut<'b, To>(&'b mut self) -> &'b mut JSRef<'a, To> { + cast::transmute(self) + } + + pub fn unrooted(&self) -> JS<T> { + JS { + ptr: self.ptr.clone() + } + } +} + +impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.deref().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.deref_mut().mut_reflector() + } +} diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 554c67e8dc6..cbbeddb8594 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -6,6 +6,7 @@ use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSTRACE_OBJECT}; +use js::jsval::JSVal; use libc; use std::cast; @@ -42,6 +43,22 @@ pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } +pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { + if !val.is_gcthing() { + return; + } + + unsafe { + description.to_c_str().with_ref(|name| { + (*tracer).debugPrinter = ptr::null(); + (*tracer).debugPrintIndex = -1; + (*tracer).debugPrintArg = name as *libc::c_void; + debug!("tracing value {:s}", description); + JS_CallTracer(tracer as *JSTracer, val.to_gcthing(), val.trace_kind()); + }); + } +} + pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) { trace_object(tracer, description, reflector.get_jsobject()) } @@ -132,3 +149,10 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<*JSObject> { Ok(()) } } + +impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<JSVal> { + fn encode(&self, s: &mut S) -> Result<(), E> { + trace_jsval(get_jstracer(s), "val", **self); + Ok(()) + } +} diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 417d4c434c2..a99189ae161 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::{FromJSValConvertible, IDLInterface}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, Root}; use dom::bindings::trace::Untraceable; use dom::browsercontext; use dom::window; @@ -37,7 +37,6 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString}; -use js::jsapi::{JS_AllowGC, JS_InhibitGC}; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsval::JSVal; use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue}; @@ -390,10 +389,10 @@ pub trait Reflectable { pub fn reflect_dom_object<T: Reflectable> (obj: ~T, - window: &JS<window::Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<window::Window>, ~T) -> JS<T>) - -> JS<T> { - JS::new(obj, window, wrap_fn) + window: &JSRef<window::Window>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<window::Window>, ~T) -> JS<T>) + -> Temporary<T> { + Temporary::new(wrap_fn(window.deref().get_cx(), window, obj)) } #[deriving(Eq)] @@ -413,6 +412,13 @@ impl Reflector { self.object = object; } + /// Return a pointer to the memory location at which the JS reflector object is stored. + /// Used by Temporary values to root the reflector, as required by the JSAPI rooting + /// APIs. + pub fn rootable<'a>(&'a self) -> &'a *JSObject { + &self.object + } + pub fn new() -> Reflector { Reflector { object: ptr::null(), @@ -605,11 +611,13 @@ pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject unsafe { debug!("outerizing"); let obj = *obj.unnamed; - let win: JS<window::Window> = + let win: Root<window::Window> = unwrap_jsmanaged(obj, IDLInterface::get_prototype_id(None::<window::Window>), - IDLInterface::get_prototype_depth(None::<window::Window>)).unwrap(); - win.get().browser_context.get_ref().window_proxy() + IDLInterface::get_prototype_depth(None::<window::Window>)) + .unwrap() + .root(); + win.deref().browser_context.get_ref().window_proxy() } } @@ -625,8 +633,8 @@ pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> { } fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { - let win = global_object_for_js_object(obj); - let js_info = win.get().page().js_info(); + let win = global_object_for_js_object(obj).root(); + let js_info = win.deref().page().js_info(); match *js_info { Some(ref info) => info.js_context.deref().deref().ptr, None => fail!("no JS context for DOM global") @@ -637,26 +645,6 @@ pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext { cx_for_dom_reflector(obj.reflector().get_jsobject()) } -/// Execute arbitrary code with the JS GC enabled, then disable it afterwards. -pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_AllowGC(cx); - let rv = f(); - JS_InhibitGC(cx); - rv - } -} - -/// Execute arbitrary code with the JS GC disabled, then enable it afterwards. -pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_InhibitGC(cx); - let rv = f(); - JS_AllowGC(cx); - rv - } -} - /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name /// for details. #[deriving(Eq)] diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs index 04964af092e..ff5958478b6 100644 --- a/src/components/script/dom/blob.rs +++ b/src/components/script/dom/blob.rs @@ -2,7 +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::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::bindings::codegen::BindingDeclarations::BlobBinding; @@ -16,38 +16,46 @@ pub struct Blob { } impl Blob { - pub fn new_inherited(window: JS<Window>) -> Blob { + pub fn new_inherited(window: &JSRef<Window>) -> Blob { Blob { reflector_: Reflector::new(), - window: window + window: window.unrooted() } } - pub fn new(window: &JS<Window>) -> JS<Blob> { - reflect_dom_object(~Blob::new_inherited(window.clone()), + pub fn new(window: &JSRef<Window>) -> Temporary<Blob> { + reflect_dom_object(~Blob::new_inherited(window), window, BlobBinding::Wrap) } -} -impl Blob { - pub fn Constructor(window: &JS<Window>) -> Fallible<JS<Blob>> { + pub fn Constructor(window: &JSRef<Window>) -> Fallible<Temporary<Blob>> { Ok(Blob::new(window)) } +} + +pub trait BlobMethods { + fn Size(&self) -> u64; + fn Type(&self) -> DOMString; + fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> Temporary<Blob>; + fn Close(&self); +} - pub fn Size(&self) -> u64 { +impl<'a> BlobMethods for JSRef<'a, Blob> { + fn Size(&self) -> u64 { 0 } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> JS<Blob> { - Blob::new(&self.window) + fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> Temporary<Blob> { + let window = self.window.root(); + Blob::new(&window.root_ref()) } - pub fn Close(&self) {} + fn Close(&self) {} } impl Reflectable for Blob { diff --git a/src/components/script/dom/browsercontext.rs b/src/components/script/dom/browsercontext.rs index 86540c12a53..fb282a2c945 100644 --- a/src/components/script/dom/browsercontext.rs +++ b/src/components/script/dom/browsercontext.rs @@ -2,7 +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::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::trace::Traceable; use dom::bindings::utils::Reflectable; use dom::document::Document; @@ -22,7 +22,7 @@ pub struct BrowserContext { } impl BrowserContext { - pub fn new(document: &JS<Document>) -> BrowserContext { + pub fn new(document: &JSRef<Document>) -> BrowserContext { let mut context = BrowserContext { history: vec!(SessionHistoryEntry::new(document)), active_index: 0, @@ -32,13 +32,13 @@ impl BrowserContext { context } - pub fn active_document(&self) -> JS<Document> { - self.history.get(self.active_index).document.clone() + pub fn active_document(&self) -> Temporary<Document> { + Temporary::new(self.history.get(self.active_index).document.clone()) } - pub fn active_window(&self) -> JS<Window> { - let doc = self.active_document(); - doc.get().window.clone() + pub fn active_window(&self) -> Temporary<Window> { + let doc = self.active_document().root(); + Temporary::new(doc.deref().window.clone()) } pub fn window_proxy(&self) -> *JSObject { @@ -47,14 +47,14 @@ impl BrowserContext { } pub fn create_window_proxy(&self) -> *JSObject { - let win = self.active_window(); - let page = win.get().page(); + let win = self.active_window().root(); + let page = win.deref().page(); let js_info = page.js_info(); let handler = js_info.get_ref().dom_static.windowproxy_handler; assert!(handler.deref().is_not_null()); - let parent = win.get().reflector().get_jsobject(); + let parent = win.deref().reflector().get_jsobject(); let cx = js_info.get_ref().js_context.deref().deref().ptr; let wrapper = unsafe { WrapperNew(cx, parent, *handler.deref()) @@ -71,9 +71,9 @@ pub struct SessionHistoryEntry { } impl SessionHistoryEntry { - fn new(document: &JS<Document>) -> SessionHistoryEntry { + fn new(document: &JSRef<Document>) -> SessionHistoryEntry { SessionHistoryEntry { - document: document.clone(), + document: document.unrooted(), children: vec!() } } diff --git a/src/components/script/dom/characterdata.rs b/src/components/script/dom/characterdata.rs index f85246ee12c..2a41e1fee3b 100644 --- a/src/components/script/dom/characterdata.rs +++ b/src/components/script/dom/characterdata.rs @@ -5,7 +5,7 @@ //! DOM bindings for `CharacterData`. use dom::bindings::codegen::InheritTypes::CharacterDataDerived; -use dom::bindings::js::JS; +use dom::bindings::js::JSRef; use dom::bindings::error::{Fallible, ErrorResult, IndexSize}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; @@ -31,44 +31,57 @@ impl CharacterDataDerived for EventTarget { } impl CharacterData { - pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JS<Document>) -> CharacterData { + pub fn new_inherited(id: NodeTypeId, data: DOMString, document: &JSRef<Document>) -> CharacterData { CharacterData { node: Node::new_inherited(id, document), data: data } } +} + +pub trait CharacterDataMethods { + fn Data(&self) -> DOMString; + fn SetData(&mut self, arg: DOMString) -> ErrorResult; + fn Length(&self) -> u32; + fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString>; + fn AppendData(&mut self, arg: DOMString) -> ErrorResult; + fn InsertData(&mut self, _offset: u32, _arg: DOMString) -> ErrorResult; + fn DeleteData(&mut self, _offset: u32, _count: u32) -> ErrorResult; + fn ReplaceData(&mut self, _offset: u32, _count: u32, _arg: DOMString) -> ErrorResult; +} - pub fn Data(&self) -> DOMString { +impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { + fn Data(&self) -> DOMString { self.data.clone() } - pub fn SetData(&mut self, arg: DOMString) -> ErrorResult { + fn SetData(&mut self, arg: DOMString) -> ErrorResult { self.data = arg; Ok(()) } - pub fn Length(&self) -> u32 { + fn Length(&self) -> u32 { self.data.len() as u32 } - pub fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString> { + fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString> { Ok(self.data.slice(offset as uint, count as uint).to_str()) } - pub fn AppendData(&mut self, arg: DOMString) -> ErrorResult { + fn AppendData(&mut self, arg: DOMString) -> ErrorResult { self.data.push_str(arg); Ok(()) } - pub fn InsertData(&mut self, offset: u32, arg: DOMString) -> ErrorResult { + fn InsertData(&mut self, offset: u32, arg: DOMString) -> ErrorResult { self.ReplaceData(offset, 0, arg) } - pub fn DeleteData(&mut self, offset: u32, count: u32) -> ErrorResult { + fn DeleteData(&mut self, offset: u32, count: u32) -> ErrorResult { self.ReplaceData(offset, count, ~"") } - pub fn ReplaceData(&mut self, offset: u32, count: u32, arg: DOMString) -> ErrorResult { + fn ReplaceData(&mut self, offset: u32, count: u32, arg: DOMString) -> ErrorResult { let length = self.data.len() as u32; if offset > length { return Err(IndexSize); diff --git a/src/components/script/dom/clientrect.rs b/src/components/script/dom/clientrect.rs index 3d84944dfaa..316269bfc56 100644 --- a/src/components/script/dom/clientrect.rs +++ b/src/components/script/dom/clientrect.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::ClientRectBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::geometry::Au; @@ -19,7 +19,7 @@ pub struct ClientRect { } impl ClientRect { - pub fn new_inherited(window: JS<Window>, + pub fn new_inherited(window: &JSRef<Window>, top: Au, bottom: Au, left: Au, right: Au) -> ClientRect { ClientRect { @@ -28,39 +28,49 @@ impl ClientRect { left: left.to_nearest_px() as f32, right: right.to_nearest_px() as f32, reflector_: Reflector::new(), - window: window, + window: window.unrooted(), } } - pub fn new(window: &JS<Window>, + pub fn new(window: &JSRef<Window>, top: Au, bottom: Au, - left: Au, right: Au) -> JS<ClientRect> { - let rect = ClientRect::new_inherited(window.clone(), top, bottom, left, right); + left: Au, right: Au) -> Temporary<ClientRect> { + let rect = ClientRect::new_inherited(window, top, bottom, left, right); reflect_dom_object(~rect, window, ClientRectBinding::Wrap) } +} +pub trait ClientRectMethods { + fn Top(&self) -> f32; + fn Bottom(&self) -> f32; + fn Left(&self) -> f32; + fn Right(&self) -> f32; + fn Width(&self) -> f32; + fn Height(&self) -> f32; +} - pub fn Top(&self) -> f32 { +impl<'a> ClientRectMethods for JSRef<'a, ClientRect> { + fn Top(&self) -> f32 { self.top } - pub fn Bottom(&self) -> f32 { + fn Bottom(&self) -> f32 { self.bottom } - pub fn Left(&self) -> f32 { + fn Left(&self) -> f32 { self.left } - pub fn Right(&self) -> f32 { + fn Right(&self) -> f32 { self.right } - pub fn Width(&self) -> f32 { + fn Width(&self) -> f32 { (self.right - self.left).abs() } - pub fn Height(&self) -> f32 { + fn Height(&self) -> f32 { (self.bottom - self.top).abs() } } diff --git a/src/components/script/dom/clientrectlist.rs b/src/components/script/dom/clientrectlist.rs index 906cfaa65e9..d48cfadf2d7 100644 --- a/src/components/script/dom/clientrectlist.rs +++ b/src/components/script/dom/clientrectlist.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::ClientRectListBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::clientrect::ClientRect; use dom::window::Window; @@ -16,34 +16,42 @@ pub struct ClientRectList { } impl ClientRectList { - pub fn new_inherited(window: JS<Window>, - rects: Vec<JS<ClientRect>>) -> ClientRectList { + pub fn new_inherited(window: &JSRef<Window>, + rects: Vec<JSRef<ClientRect>>) -> ClientRectList { ClientRectList { reflector_: Reflector::new(), - rects: rects, - window: window, + rects: rects.iter().map(|rect| rect.unrooted()).collect(), + window: window.unrooted(), } } - pub fn new(window: &JS<Window>, - rects: Vec<JS<ClientRect>>) -> JS<ClientRectList> { - reflect_dom_object(~ClientRectList::new_inherited(window.clone(), rects), + pub fn new(window: &JSRef<Window>, + rects: Vec<JSRef<ClientRect>>) -> Temporary<ClientRectList> { + reflect_dom_object(~ClientRectList::new_inherited(window, rects), window, ClientRectListBinding::Wrap) } +} + +pub trait ClientRectListMethods { + fn Length(&self) -> u32; + fn Item(&self, index: u32) -> Option<Temporary<ClientRect>>; + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<ClientRect>>; +} - pub fn Length(&self) -> u32 { +impl<'a> ClientRectListMethods for JSRef<'a, ClientRectList> { + fn Length(&self) -> u32 { self.rects.len() as u32 } - pub fn Item(&self, index: u32) -> Option<JS<ClientRect>> { + fn Item(&self, index: u32) -> Option<Temporary<ClientRect>> { if index < self.rects.len() as u32 { - Some(self.rects.get(index as uint).clone()) + Some(Temporary::new(self.rects.get(index as uint).clone())) } else { None } } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<ClientRect>> { + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<ClientRect>> { *found = index < self.rects.len() as u32; self.Item(index) } diff --git a/src/components/script/dom/comment.rs b/src/components/script/dom/comment.rs index d6681c6ba2a..0e314324e57 100644 --- a/src/components/script/dom/comment.rs +++ b/src/components/script/dom/comment.rs @@ -4,13 +4,13 @@ use dom::bindings::codegen::InheritTypes::CommentDerived; use dom::bindings::codegen::BindingDeclarations::CommentBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::Fallible; use dom::characterdata::CharacterData; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::node::{CommentNodeTypeId, Node}; -use dom::window::Window; +use dom::window::{Window, WindowMethods}; use servo_util::str::DOMString; /// An HTML comment. @@ -29,18 +29,22 @@ impl CommentDerived for EventTarget { } impl Comment { - pub fn new_inherited(text: DOMString, document: JS<Document>) -> Comment { + pub fn new_inherited(text: DOMString, document: &JSRef<Document>) -> Comment { Comment { characterdata: CharacterData::new_inherited(CommentNodeTypeId, text, document) } } - pub fn new(text: DOMString, document: &JS<Document>) -> JS<Comment> { - let node = Comment::new_inherited(text, document.clone()); + pub fn new(text: DOMString, document: &JSRef<Document>) -> Temporary<Comment> { + let node = Comment::new_inherited(text, document); Node::reflect_node(~node, document, CommentBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, data: DOMString) -> Fallible<JS<Comment>> { - Ok(Comment::new(data, &owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>, data: DOMString) -> Fallible<Temporary<Comment>> { + let document = owner.Document().root(); + Ok(Comment::new(data, &*document)) } } + +pub trait CommentMethods { +} diff --git a/src/components/script/dom/console.rs b/src/components/script/dom/console.rs index 8e8081dcd83..a9c60962359 100644 --- a/src/components/script/dom/console.rs +++ b/src/components/script/dom/console.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::ConsoleBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::str::DOMString; @@ -20,27 +20,37 @@ impl Console { } } - pub fn new(window: &JS<Window>) -> JS<Console> { + pub fn new(window: &JSRef<Window>) -> Temporary<Console> { reflect_dom_object(~Console::new_inherited(), window, ConsoleBinding::Wrap) } +} + +pub trait ConsoleMethods { + fn Log(&self, message: DOMString); + fn Debug(&self, message: DOMString); + fn Info(&self, message: DOMString); + fn Warn(&self, message: DOMString); + fn Error(&self, message: DOMString); +} - pub fn Log(&self, message: DOMString) { +impl<'a> ConsoleMethods for JSRef<'a, Console> { + fn Log(&self, message: DOMString) { println!("{:s}", message); } - pub fn Debug(&self, message: DOMString) { + fn Debug(&self, message: DOMString) { println!("{:s}", message); } - pub fn Info(&self, message: DOMString) { + fn Info(&self, message: DOMString) { println!("{:s}", message); } - pub fn Warn(&self, message: DOMString) { + fn Warn(&self, message: DOMString) { println!("{:s}", message); } - pub fn Error(&self, message: DOMString) { + fn Error(&self, message: DOMString) { println!("{:s}", message); } } diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index fdf47a5467d..d911611eba3 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::InheritTypes::{DocumentDerived, EventCast, HTMLElementCast}; -use dom::bindings::codegen::InheritTypes::{DocumentBase, NodeCast, DocumentCast}; use dom::bindings::codegen::InheritTypes::{HTMLHeadElementCast, TextCast, ElementCast}; -use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast}; +use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast, NodeCast}; use dom::bindings::codegen::BindingDeclarations::DocumentBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, TemporaryPushable}; +use dom::bindings::js::OptionalRootable; use dom::bindings::trace::Untraceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError}; @@ -22,18 +22,18 @@ use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; use dom::event::Event; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::{HTMLCollection, CollectionFilter}; -use dom::nodelist::NodeList; use dom::htmlelement::HTMLElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmltitleelement::HTMLTitleElement; use dom::mouseevent::MouseEvent; -use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, INode}; +use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, NodeMethods}; use dom::node::{CloneChildren, DoNotCloneChildren}; +use dom::nodelist::NodeList; use dom::text::Text; use dom::processinginstruction::ProcessingInstruction; use dom::uievent::UIEvent; -use dom::window::Window; +use dom::window::{Window, WindowMethods}; use dom::location::Location; use html::hubbub_html_parser::build_element_from_tag; use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks}; @@ -76,23 +76,127 @@ impl DocumentDerived for EventTarget { } } +pub trait DocumentHelpers { + fn url<'a>(&'a self) -> &'a Url; + fn quirks_mode(&self) -> QuirksMode; + fn set_quirks_mode(&mut self, mode: QuirksMode); + fn set_encoding_name(&mut self, name: DOMString); + fn content_changed(&self); + fn damage_and_reflow(&self, damage: DocumentDamageLevel); + fn wait_until_safe_to_modify_dom(&self); + fn unregister_named_element(&mut self, to_unregister: &JSRef<Element>, id: DOMString); + fn register_named_element(&mut self, element: &JSRef<Element>, id: DOMString); +} + +impl<'a> DocumentHelpers for JSRef<'a, Document> { + fn url<'a>(&'a self) -> &'a Url { + &*self.url + } + + fn quirks_mode(&self) -> QuirksMode { + *self.quirks_mode + } + + fn set_quirks_mode(&mut self, mode: QuirksMode) { + *self.quirks_mode = mode; + } + + fn set_encoding_name(&mut self, name: DOMString) { + self.encoding_name = name; + } + + fn content_changed(&self) { + self.damage_and_reflow(ContentChangedDocumentDamage); + } + + fn damage_and_reflow(&self, damage: DocumentDamageLevel) { + self.window.root().damage_and_reflow(damage); + } + + fn wait_until_safe_to_modify_dom(&self) { + self.window.root().wait_until_safe_to_modify_dom(); + } + + + /// Remove any existing association between the provided id and any elements in this document. + fn unregister_named_element(&mut self, + to_unregister: &JSRef<Element>, + id: DOMString) { + let mut is_empty = false; + match self.idmap.find_mut(&id) { + None => {}, + Some(elements) => { + let position = elements.iter() + .map(|elem| elem.root()) + .position(|element| &*element == to_unregister) + .expect("This element should be in registered."); + elements.remove(position); + is_empty = elements.is_empty(); + } + } + if is_empty { + self.idmap.remove(&id); + } + } + + /// Associate an element present in this document with the provided id. + fn register_named_element(&mut self, + element: &JSRef<Element>, + id: DOMString) { + assert!({ + let node: &JSRef<Node> = NodeCast::from_ref(element); + node.is_in_doc() + }); + + // FIXME https://github.com/mozilla/rust/issues/13195 + // Use mangle() when it exists again. + let root = self.GetDocumentElement().expect("The element is in the document, so there must be a document element.").root(); + match self.idmap.find_mut(&id) { + Some(elements) => { + let new_node: &JSRef<Node> = NodeCast::from_ref(element); + let mut head : uint = 0u; + let root: &JSRef<Node> = NodeCast::from_ref(&*root); + for node in root.traverse_preorder() { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + match elem { + Some(elem) => { + if &*elements.get(head).root() == elem { + head = head + 1; + } + if new_node == &node || head == elements.len() { + break; + } + } + None => {} + } + } + elements.insert_unrooted(head, element); + return; + }, + None => (), + } + let mut elements = vec!(); + elements.push_unrooted(element); + self.idmap.insert(id, elements); + } +} + impl Document { - pub fn reflect_document<D: Reflectable+DocumentBase> - (document: ~D, - window: &JS<Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~D) -> JS<D>) - -> JS<D> { + pub fn reflect_document(document: ~Document, + window: &JSRef<Window>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~Document) -> JS<Document>) + -> Temporary<Document> { assert!(document.reflector().get_jsobject().is_null()); - let raw_doc = reflect_dom_object(document, window, wrap_fn); + let mut raw_doc = reflect_dom_object(document, window, wrap_fn).root(); assert!(raw_doc.reflector().get_jsobject().is_not_null()); - let document = DocumentCast::from(&raw_doc); - let mut node: JS<Node> = NodeCast::from(&document); - node.get_mut().set_owner_doc(&document); - raw_doc + let mut doc_alias = raw_doc.clone(); + let node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut doc_alias); + node.set_owner_doc(&*raw_doc); + Temporary::from_rooted(&*raw_doc) } - pub fn new_inherited(window: JS<Window>, + pub fn new_inherited(window: &JSRef<Window>, url: Option<Url>, is_html_document: IsHTMLDocument, content_type: Option<DOMString>) -> Document { @@ -101,7 +205,7 @@ impl Document { Document { node: Node::new_without_doc(DocumentNodeTypeId), reflector_: Reflector::new(), - window: window, + window: window.unrooted(), idmap: HashMap::new(), implementation: None, content_type: match content_type { @@ -122,23 +226,15 @@ impl Document { } } - pub fn new(window: &JS<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> JS<Document> { - let document = Document::new_inherited(window.clone(), url, doctype, content_type); - Document::reflect_document(~document, window, DocumentBinding::Wrap) - } -} - -impl Document { - pub fn url<'a>(&'a self) -> &'a Url { - &*self.url - } -} - -impl Document { // http://dom.spec.whatwg.org/#dom-document - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<Document>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Temporary<Document>> { Ok(Document::new(owner, None, NonHTMLDocument, None)) } + + pub fn new(window: &JSRef<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> Temporary<Document> { + let document = Document::new_inherited(window, url, doctype, content_type); + Document::reflect_document(~document, window, DocumentBinding::Wrap) + } } impl Reflectable for Document { @@ -151,108 +247,183 @@ impl Reflectable for Document { } } -impl Document { +trait PrivateDocumentHelpers { + fn createNodeList(&self, callback: |node: &JSRef<Node>| -> bool) -> Temporary<NodeList>; + fn get_html_element(&self) -> Option<Temporary<HTMLHtmlElement>>; +} + +impl<'a> PrivateDocumentHelpers for JSRef<'a, Document> { + fn createNodeList(&self, callback: |node: &JSRef<Node>| -> bool) -> Temporary<NodeList> { + let window = self.window.root(); + + match self.GetDocumentElement().root() { + None => { + NodeList::new_simple_list(&*window, vec!()) + }, + Some(root) => { + let mut nodes = vec!(); + let root: &JSRef<Node> = NodeCast::from_ref(&*root); + for child in root.traverse_preorder() { + if callback(&child) { + nodes.push(child); + } + } + NodeList::new_simple_list(&*window, nodes) + } + } + + } + + fn get_html_element(&self) -> Option<Temporary<HTMLHtmlElement>> { + self.GetDocumentElement().root().filtered(|root| { + root.node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId) + }).map(|elem| { + Temporary::from_rooted(HTMLHtmlElementCast::to_ref(&*elem).unwrap()) + }) + } +} + +pub trait DocumentMethods { + fn Implementation(&mut self) -> Temporary<DOMImplementation>; + fn URL(&self) -> DOMString; + fn DocumentURI(&self) -> DOMString; + fn CompatMode(&self) -> DOMString; + fn CharacterSet(&self) -> DOMString; + fn ContentType(&self) -> DOMString; + fn GetDoctype(&self) -> Option<Temporary<DocumentType>>; + fn GetDocumentElement(&self) -> Option<Temporary<Element>>; + fn GetElementsByTagName(&self, tag_name: DOMString) -> Temporary<HTMLCollection>; + fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, tag_name: DOMString) -> Temporary<HTMLCollection>; + fn GetElementsByClassName(&self, classes: DOMString) -> Temporary<HTMLCollection>; + fn GetElementById(&self, id: DOMString) -> Option<Temporary<Element>>; + fn CreateElement(&self, local_name: DOMString) -> Fallible<Temporary<Element>>; + fn CreateElementNS(&self, namespace: Option<DOMString>, qualified_name: DOMString) -> Fallible<Temporary<Element>>; + fn CreateDocumentFragment(&self) -> Temporary<DocumentFragment>; + fn CreateTextNode(&self, data: DOMString) -> Temporary<Text>; + fn CreateComment(&self, data: DOMString) -> Temporary<Comment>; + fn CreateProcessingInstruction(&self, target: DOMString, data: DOMString) -> Fallible<Temporary<ProcessingInstruction>>; + fn ImportNode(&self, node: &JSRef<Node>, deep: bool) -> Fallible<Temporary<Node>>; + fn AdoptNode(&self, node: &mut JSRef<Node>) -> Fallible<Temporary<Node>>; + fn CreateEvent(&self, interface: DOMString) -> Fallible<Temporary<Event>>; + fn Title(&self) -> DOMString; + fn SetTitle(&self, title: DOMString) -> ErrorResult; + fn GetHead(&self) -> Option<Temporary<HTMLHeadElement>>; + fn GetBody(&self) -> Option<Temporary<HTMLElement>>; + fn SetBody(&self, new_body: Option<JSRef<HTMLElement>>) -> ErrorResult; + fn GetElementsByName(&self, name: DOMString) -> Temporary<NodeList>; + fn Images(&self) -> Temporary<HTMLCollection>; + fn Embeds(&self) -> Temporary<HTMLCollection>; + fn Plugins(&self) -> Temporary<HTMLCollection>; + fn Links(&self) -> Temporary<HTMLCollection>; + fn Forms(&self) -> Temporary<HTMLCollection>; + fn Scripts(&self) -> Temporary<HTMLCollection>; + fn Anchors(&self) -> Temporary<HTMLCollection>; + fn Applets(&self) -> Temporary<HTMLCollection>; + fn Location(&mut self) -> Temporary<Location>; + fn Children(&self) -> Temporary<HTMLCollection>; +} + +impl<'a> DocumentMethods for JSRef<'a, Document> { // http://dom.spec.whatwg.org/#dom-document-implementation - pub fn Implementation(&mut self) -> JS<DOMImplementation> { + fn Implementation(&mut self) -> Temporary<DOMImplementation> { if self.implementation.is_none() { - self.implementation = Some(DOMImplementation::new(&self.window)); + let window = self.window.root(); + self.implementation.assign(Some(DOMImplementation::new(&*window))); } - self.implementation.get_ref().clone() + Temporary::new(self.implementation.get_ref().clone()) } // http://dom.spec.whatwg.org/#dom-document-url - pub fn URL(&self) -> DOMString { + fn URL(&self) -> DOMString { self.url().to_str() } // http://dom.spec.whatwg.org/#dom-document-documenturi - pub fn DocumentURI(&self) -> DOMString { + fn DocumentURI(&self) -> DOMString { self.URL() } // http://dom.spec.whatwg.org/#dom-document-compatmode - pub fn CompatMode(&self) -> DOMString { + fn CompatMode(&self) -> DOMString { match *self.quirks_mode { NoQuirks => ~"CSS1Compat", LimitedQuirks | FullQuirks => ~"BackCompat" } } - pub fn quirks_mode(&self) -> QuirksMode { - *self.quirks_mode - } - - pub fn set_quirks_mode(&mut self, mode: QuirksMode) { - *self.quirks_mode = mode; - } - // http://dom.spec.whatwg.org/#dom-document-characterset - pub fn CharacterSet(&self) -> DOMString { + fn CharacterSet(&self) -> DOMString { self.encoding_name.to_ascii_lower() } - pub fn set_encoding_name(&mut self, name: DOMString) { - self.encoding_name = name; - } - // http://dom.spec.whatwg.org/#dom-document-content_type - pub fn ContentType(&self) -> DOMString { + fn ContentType(&self) -> DOMString { self.content_type.clone() } // http://dom.spec.whatwg.org/#dom-document-doctype - pub fn GetDoctype(&self) -> Option<JS<DocumentType>> { - self.node.children().find(|child| child.is_doctype()) - .map(|node| DocumentTypeCast::to(&node).unwrap()) + fn GetDoctype(&self) -> Option<Temporary<DocumentType>> { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.children().find(|child| { + child.is_doctype() + }).map(|node| { + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap(); + Temporary::from_rooted(doctype) + }) } // http://dom.spec.whatwg.org/#dom-document-documentelement - pub fn GetDocumentElement(&self) -> Option<JS<Element>> { - self.node.child_elements().next() + fn GetDocumentElement(&self) -> Option<Temporary<Element>> { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.child_elements().next().map(|elem| Temporary::from_rooted(&elem)) } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagname - pub fn GetElementsByTagName(&self, abstract_self: &JS<Document>, tag_name: DOMString) -> JS<HTMLCollection> { - HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), tag_name) + fn GetElementsByTagName(&self, tag_name: DOMString) -> Temporary<HTMLCollection> { + let window = self.window.root(); + HTMLCollection::by_tag_name(&*window, NodeCast::from_ref(self), tag_name) } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens - pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<Document>, maybe_ns: Option<DOMString>, tag_name: DOMString) -> JS<HTMLCollection> { + fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, tag_name: DOMString) -> Temporary<HTMLCollection> { + let window = self.window.root(); + let namespace = match maybe_ns { Some(namespace) => Namespace::from_str(namespace), None => Null }; - HTMLCollection::by_tag_name_ns(&self.window, &NodeCast::from(abstract_self), tag_name, namespace) + HTMLCollection::by_tag_name_ns(&*window, NodeCast::from_ref(self), tag_name, namespace) } // http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname - pub fn GetElementsByClassName(&self, abstract_self: &JS<Document>, classes: DOMString) -> JS<HTMLCollection> { - HTMLCollection::by_class_name(&self.window, &NodeCast::from(abstract_self), classes) + fn GetElementsByClassName(&self, classes: DOMString) -> Temporary<HTMLCollection> { + let window = self.window.root(); + + HTMLCollection::by_class_name(&*window, NodeCast::from_ref(self), classes) } // http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid - pub fn GetElementById(&self, id: DOMString) -> Option<JS<Element>> { + fn GetElementById(&self, id: DOMString) -> Option<Temporary<Element>> { match self.idmap.find_equiv(&id) { None => None, - Some(ref elements) => Some(elements.get(0).clone()), + Some(ref elements) => Some(Temporary::new(elements.get(0).clone())), } } // http://dom.spec.whatwg.org/#dom-document-createelement - pub fn CreateElement(&self, abstract_self: &JS<Document>, local_name: DOMString) - -> Fallible<JS<Element>> { + fn CreateElement(&self, local_name: DOMString) -> Fallible<Temporary<Element>> { if xml_name_type(local_name) == InvalidXMLName { debug!("Not a valid element name"); return Err(InvalidCharacter); } let local_name = local_name.to_ascii_lower(); - Ok(build_element_from_tag(local_name, abstract_self)) + Ok(build_element_from_tag(local_name, self)) } // http://dom.spec.whatwg.org/#dom-document-createelementns - pub fn CreateElementNS(&self, abstract_self: &JS<Document>, - namespace: Option<DOMString>, - qualified_name: DOMString) -> Fallible<JS<Element>> { + fn CreateElementNS(&self, + namespace: Option<DOMString>, + qualified_name: DOMString) -> Fallible<Temporary<Element>> { let ns = Namespace::from_str(null_str_as_empty_ref(&namespace)); match xml_name_type(qualified_name) { InvalidXMLName => { @@ -289,31 +460,31 @@ impl Document { } if ns == namespace::HTML { - Ok(build_element_from_tag(local_name_from_qname, abstract_self)) + Ok(build_element_from_tag(local_name_from_qname, self)) } else { - Ok(Element::new(local_name_from_qname, ns, prefix_from_qname, abstract_self)) + Ok(Element::new(local_name_from_qname, ns, prefix_from_qname, self)) } } // http://dom.spec.whatwg.org/#dom-document-createdocumentfragment - pub fn CreateDocumentFragment(&self, abstract_self: &JS<Document>) -> JS<DocumentFragment> { - DocumentFragment::new(abstract_self) + fn CreateDocumentFragment(&self) -> Temporary<DocumentFragment> { + DocumentFragment::new(self) } // http://dom.spec.whatwg.org/#dom-document-createtextnode - pub fn CreateTextNode(&self, abstract_self: &JS<Document>, data: DOMString) - -> JS<Text> { - Text::new(data, abstract_self) + fn CreateTextNode(&self, data: DOMString) + -> Temporary<Text> { + Text::new(data, self) } // http://dom.spec.whatwg.org/#dom-document-createcomment - pub fn CreateComment(&self, abstract_self: &JS<Document>, data: DOMString) -> JS<Comment> { - Comment::new(data, abstract_self) + fn CreateComment(&self, data: DOMString) -> Temporary<Comment> { + Comment::new(data, self) } // http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction - pub fn CreateProcessingInstruction(&self, abstract_self: &JS<Document>, target: DOMString, - data: DOMString) -> Fallible<JS<ProcessingInstruction>> { + fn CreateProcessingInstruction(&self, target: DOMString, + data: DOMString) -> Fallible<Temporary<ProcessingInstruction>> { // Step 1. if xml_name_type(target) == InvalidXMLName { return Err(InvalidCharacter); @@ -325,11 +496,11 @@ impl Document { } // Step 3. - Ok(ProcessingInstruction::new(target, data, abstract_self)) + Ok(ProcessingInstruction::new(target, data, self)) } // http://dom.spec.whatwg.org/#dom-document-importnode - pub fn ImportNode(&self, abstract_self: &JS<Document>, node: &JS<Node>, deep: bool) -> Fallible<JS<Node>> { + fn ImportNode(&self, node: &JSRef<Node>, deep: bool) -> Fallible<Temporary<Node>> { // Step 1. if node.is_document() { return Err(NotSupported); @@ -341,47 +512,48 @@ impl Document { false => DoNotCloneChildren }; - Ok(Node::clone(node, Some(abstract_self), clone_children)) + Ok(Node::clone(node, Some(self), clone_children)) } // http://dom.spec.whatwg.org/#dom-document-adoptnode - pub fn AdoptNode(&self, abstract_self: &JS<Document>, node: &JS<Node>) -> Fallible<JS<Node>> { + fn AdoptNode(&self, node: &mut JSRef<Node>) -> Fallible<Temporary<Node>> { // Step 1. if node.is_document() { return Err(NotSupported); } // Step 2. - let mut adoptee = node.clone(); - Node::adopt(&mut adoptee, abstract_self); + Node::adopt(node, self); // Step 3. - Ok(adoptee) + Ok(Temporary::from_rooted(node)) } // http://dom.spec.whatwg.org/#dom-document-createevent - pub fn CreateEvent(&self, interface: DOMString) -> Fallible<JS<Event>> { + fn CreateEvent(&self, interface: DOMString) -> Fallible<Temporary<Event>> { + let window = self.window.root(); + match interface.to_ascii_lower().as_slice() { // FIXME: Implement CustomEvent (http://dom.spec.whatwg.org/#customevent) - "uievents" | "uievent" => Ok(EventCast::from(&UIEvent::new(&self.window))), - "mouseevents" | "mouseevent" => Ok(EventCast::from(&MouseEvent::new(&self.window))), - "htmlevents" | "events" | "event" => Ok(Event::new(&self.window)), + "uievents" | "uievent" => Ok(EventCast::from_unrooted(UIEvent::new(&*window))), + "mouseevents" | "mouseevent" => Ok(EventCast::from_unrooted(MouseEvent::new(&*window))), + "htmlevents" | "events" | "event" => Ok(Event::new(&*window)), _ => Err(NotSupported) } } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn Title(&self, _: &JS<Document>) -> DOMString { + fn Title(&self) -> DOMString { let mut title = ~""; - self.GetDocumentElement().map(|root| { - let root: JS<Node> = NodeCast::from(&root); + self.GetDocumentElement().root().map(|root| { + let root: &JSRef<Node> = NodeCast::from_ref(&*root); root.traverse_preorder() .find(|node| node.type_id() == ElementNodeTypeId(HTMLTitleElementTypeId)) .map(|title_elem| { for child in title_elem.children() { if child.is_text() { - let text: JS<Text> = TextCast::to(&child).unwrap(); - title.push_str(text.get().characterdata.data.as_slice()); + let text: &JSRef<Text> = TextCast::to_ref(&child).unwrap(); + title.push_str(text.deref().characterdata.data.as_slice()); } } }); @@ -392,15 +564,15 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn SetTitle(&self, abstract_self: &JS<Document>, title: DOMString) -> ErrorResult { - self.GetDocumentElement().map(|root| { - let root: JS<Node> = NodeCast::from(&root); + fn SetTitle(&self, title: DOMString) -> ErrorResult { + self.GetDocumentElement().root().map(|root| { + let root: &JSRef<Node> = NodeCast::from_ref(&*root); let mut head_node = root.traverse_preorder().find(|child| { - child.get().type_id == ElementNodeTypeId(HTMLHeadElementTypeId) + child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId) }); head_node.as_mut().map(|head| { let mut title_node = head.children().find(|child| { - child.get().type_id == ElementNodeTypeId(HTMLTitleElementTypeId) + child.type_id() == ElementNodeTypeId(HTMLTitleElementTypeId) }); match title_node { @@ -408,15 +580,18 @@ impl Document { for mut title_child in title_node.children() { assert!(title_node.RemoveChild(&mut title_child).is_ok()); } - let new_text = self.CreateTextNode(abstract_self, title.clone()); - assert!(title_node.AppendChild(&mut NodeCast::from(&new_text)).is_ok()); + let mut new_text = self.CreateTextNode(title.clone()).root(); + + assert!(title_node.AppendChild(NodeCast::from_mut_ref(&mut *new_text)).is_ok()); }, None => { - let mut new_title: JS<Node> = - NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self)); - let new_text = self.CreateTextNode(abstract_self, title.clone()); - assert!(new_title.AppendChild(&mut NodeCast::from(&new_text)).is_ok()); - assert!(head.AppendChild(&mut new_title).is_ok()); + let mut new_title = HTMLTitleElement::new(~"title", self).root(); + let new_title: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *new_title); + + let mut new_text = self.CreateTextNode(title.clone()).root(); + + assert!(new_title.AppendChild(NodeCast::from_mut_ref(&mut *new_text)).is_ok()); + assert!(head.AppendChild(&mut *new_title).is_ok()); }, } }); @@ -424,42 +599,43 @@ impl Document { Ok(()) } - fn get_html_element(&self) -> Option<JS<HTMLHtmlElement>> { - self.GetDocumentElement().filtered(|root| { - root.get().node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId) - }).map(|elem| HTMLHtmlElementCast::to(&elem).unwrap()) - } - // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-head - pub fn GetHead(&self) -> Option<JS<HTMLHeadElement>> { + fn GetHead(&self) -> Option<Temporary<HTMLHeadElement>> { self.get_html_element().and_then(|root| { - let node: JS<Node> = NodeCast::from(&root); + let root = root.root(); + let node: &JSRef<Node> = NodeCast::from_ref(&*root); node.children().find(|child| { child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId) - }).map(|node| HTMLHeadElementCast::to(&node).unwrap()) + }).map(|node| { + Temporary::from_rooted(HTMLHeadElementCast::to_ref(&node).unwrap()) + }) }) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn GetBody(&self, _: &JS<Document>) -> Option<JS<HTMLElement>> { + fn GetBody(&self) -> Option<Temporary<HTMLElement>> { self.get_html_element().and_then(|root| { - let node: JS<Node> = NodeCast::from(&root); + let root = root.root(); + let node: &JSRef<Node> = NodeCast::from_ref(&*root); node.children().find(|child| { match child.type_id() { ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => true, _ => false } - }).map(|node| HTMLElementCast::to(&node).unwrap()) + }).map(|node| { + Temporary::from_rooted(HTMLElementCast::to_ref(&node).unwrap()) + }) }) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn SetBody(&self, abstract_self: &JS<Document>, new_body: Option<JS<HTMLElement>>) -> ErrorResult { + fn SetBody(&self, new_body: Option<JSRef<HTMLElement>>) -> ErrorResult { // Step 1. match new_body { - Some(ref node) => { - match node.get().element.node.type_id { + Some(ref htmlelem) => { + let node: &JSRef<Node> = NodeCast::from_ref(htmlelem); + match node.type_id() { ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => {} _ => return Err(HierarchyRequest) } @@ -468,24 +644,28 @@ impl Document { } // Step 2. - let old_body: Option<JS<HTMLElement>> = self.GetBody(abstract_self); - if old_body == new_body { + let mut old_body = self.GetBody().root(); + //FIXME: covariant lifetime workaround. do not judge. + if old_body.as_ref().map(|body| body.deref()) == new_body.as_ref().map(|a| &*a) { return Ok(()); } // Step 3. - match self.get_html_element() { + match self.get_html_element().root() { // Step 4. None => return Err(HierarchyRequest), - Some(root) => { - let mut new_body: JS<Node> = NodeCast::from(&new_body.unwrap()); - let mut root: JS<Node> = NodeCast::from(&root); + Some(ref mut root) => { + let mut new_body_unwrapped = new_body.unwrap(); + let new_body: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut new_body_unwrapped); + + let root: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut **root); match old_body { - Some(child) => { - let mut child: JS<Node> = NodeCast::from(&child); - assert!(root.ReplaceChild(&mut new_body, &mut child).is_ok()) + Some(ref mut child) => { + let child: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut **child); + + assert!(root.ReplaceChild(new_body, child).is_ok()) } - None => assert!(root.AppendChild(&mut new_body).is_ok()) + None => assert!(root.AppendChild(new_body).is_ok()) }; } } @@ -493,204 +673,130 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname - pub fn GetElementsByName(&self, name: DOMString) -> JS<NodeList> { + fn GetElementsByName(&self, name: DOMString) -> Temporary<NodeList> { self.createNodeList(|node| { if !node.is_element() { return false; } - let element: JS<Element> = ElementCast::to(node).unwrap(); - element.get_attribute(Null, "name").map_or(false, |attr| { - attr.get().value_ref() == name + let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + element.get_attribute(Null, "name").root().map_or(false, |mut attr| { + attr.value_ref() == name }) }) } - pub fn Images(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Images(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct ImagesFilter; impl CollectionFilter for ImagesFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"img" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"img" } } let filter = ~ImagesFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Embeds(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Embeds(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct EmbedsFilter; impl CollectionFilter for EmbedsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"embed" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"embed" } } let filter = ~EmbedsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Plugins(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Plugins(&self) -> Temporary<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1847 - self.Embeds(abstract_self) + self.Embeds() } - pub fn Links(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Links(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct LinksFilter; impl CollectionFilter for LinksFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - (elem.get().local_name == ~"a" || elem.get().local_name == ~"area") && + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + (elem.deref().local_name == ~"a" || elem.deref().local_name == ~"area") && elem.get_attribute(Null, "href").is_some() } } let filter = ~LinksFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Forms(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Forms(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct FormsFilter; impl CollectionFilter for FormsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"form" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"form" } } let filter = ~FormsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Scripts(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Scripts(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct ScriptsFilter; impl CollectionFilter for ScriptsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"script" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"script" } } let filter = ~ScriptsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Anchors(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct AnchorsFilter; impl CollectionFilter for AnchorsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"a" && elem.get_attribute(Null, "name").is_some() + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"a" && elem.get_attribute(Null, "name").is_some() } } let filter = ~AnchorsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - pub fn Applets(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + fn Applets(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + // FIXME: This should be return OBJECT elements containing applets. struct AppletsFilter; impl CollectionFilter for AppletsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"applet" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"applet" } } let filter = ~AppletsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) - } - - pub fn Location(&mut self, abstract_self: &JS<Document>) -> JS<Location> { - self.window.get_mut().Location(&abstract_self.get().window) - } - - pub fn Children(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) - } - - pub fn createNodeList(&self, callback: |node: &JS<Node>| -> bool) -> JS<NodeList> { - let mut nodes = vec!(); - match self.GetDocumentElement() { - None => {}, - Some(root) => { - let root: JS<Node> = NodeCast::from(&root); - for child in root.traverse_preorder() { - if callback(&child) { - nodes.push(child.clone()); - } - } - } - } - - NodeList::new_simple_list(&self.window, nodes) - } - - pub fn content_changed(&self) { - self.damage_and_reflow(ContentChangedDocumentDamage); - } - - pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) { - self.window.get().damage_and_reflow(damage); - } - - pub fn wait_until_safe_to_modify_dom(&self) { - self.window.get().wait_until_safe_to_modify_dom(); + HTMLCollection::create(&*window, NodeCast::from_ref(self), filter) } - - /// Remove any existing association between the provided id and any elements in this document. - pub fn unregister_named_element(&mut self, - abstract_self: &JS<Element>, - id: DOMString) { - let mut is_empty = false; - match self.idmap.find_mut(&id) { - None => {}, - Some(elements) => { - let position = elements.iter() - .position(|element| element == abstract_self) - .expect("This element should be in registered."); - elements.remove(position); - is_empty = elements.is_empty(); - } - } - if is_empty { - self.idmap.remove(&id); - } + fn Location(&mut self) -> Temporary<Location> { + let mut window = self.window.root(); + window.Location() } - /// Associate an element present in this document with the provided id. - pub fn register_named_element(&mut self, - element: &JS<Element>, - id: DOMString) { - assert!({ - let node: JS<Node> = NodeCast::from(element); - node.is_in_doc() - }); - - // FIXME https://github.com/mozilla/rust/issues/13195 - // Use mangle() when it exists again. - let root = self.GetDocumentElement().expect("The element is in the document, so there must be a document element."); - match self.idmap.find_mut(&id) { - Some(elements) => { - let new_node = NodeCast::from(element); - let mut head : uint = 0u; - let root: JS<Node> = NodeCast::from(&root); - for node in root.traverse_preorder() { - match ElementCast::to(&node) { - Some(elem) => { - if elements.get(head) == &elem { - head = head + 1; - } - if new_node == node || head == elements.len() { - break; - } - } - None => {} - } - } - elements.insert(head, element.clone()); - return; - }, - None => (), - } - self.idmap.insert(id, vec!(element.clone())); + fn Children(&self) -> Temporary<HTMLCollection> { + let window = self.window.root(); + HTMLCollection::children(&*window, NodeCast::from_ref(self)) } } diff --git a/src/components/script/dom/documentfragment.rs b/src/components/script/dom/documentfragment.rs index 7346a5a98ef..25f2c3c1d69 100644 --- a/src/components/script/dom/documentfragment.rs +++ b/src/components/script/dom/documentfragment.rs @@ -4,13 +4,13 @@ use dom::bindings::codegen::InheritTypes::{DocumentFragmentDerived, NodeCast}; use dom::bindings::codegen::BindingDeclarations::DocumentFragmentBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::Fallible; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; -use dom::node::{DocumentFragmentNodeTypeId, Node}; -use dom::window::Window; +use dom::node::{DocumentFragmentNodeTypeId, Node, window_from_node}; +use dom::window::{Window, WindowMethods}; #[deriving(Encodable)] pub struct DocumentFragment { @@ -28,28 +28,32 @@ impl DocumentFragmentDerived for EventTarget { impl DocumentFragment { /// Creates a new DocumentFragment. - pub fn new_inherited(document: JS<Document>) -> DocumentFragment { + pub fn new_inherited(document: &JSRef<Document>) -> DocumentFragment { DocumentFragment { node: Node::new_inherited(DocumentFragmentNodeTypeId, document), } } - pub fn new(document: &JS<Document>) -> JS<DocumentFragment> { - let node = DocumentFragment::new_inherited(document.clone()); + pub fn new(document: &JSRef<Document>) -> Temporary<DocumentFragment> { + let node = DocumentFragment::new_inherited(document); Node::reflect_node(~node, document, DocumentFragmentBinding::Wrap) } -} -impl DocumentFragment { - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DocumentFragment>> { - Ok(DocumentFragment::new(&owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Temporary<DocumentFragment>> { + let document = owner.Document(); + let document = document.root(); + + Ok(DocumentFragment::new(&document.root_ref())) } } -impl DocumentFragment { - pub fn Children(&self, abstract_self: &JS<DocumentFragment>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) +pub trait DocumentFragmentMethods { + fn Children(&self) -> Temporary<HTMLCollection>; +} + +impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> { + fn Children(&self) -> Temporary<HTMLCollection> { + let window = window_from_node(self).root(); + HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(self)) } } diff --git a/src/components/script/dom/documenttype.rs b/src/components/script/dom/documenttype.rs index 856dde0e98e..31312bd40f1 100644 --- a/src/components/script/dom/documenttype.rs +++ b/src/components/script/dom/documenttype.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::InheritTypes::DocumentTypeDerived; use dom::bindings::codegen::BindingDeclarations::DocumentTypeBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::node::{Node, DoctypeNodeTypeId}; @@ -32,7 +32,7 @@ impl DocumentType { pub fn new_inherited(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: JS<Document>) + document: &JSRef<Document>) -> DocumentType { DocumentType { node: Node::new_inherited(DoctypeNodeTypeId, document), @@ -45,26 +45,32 @@ impl DocumentType { pub fn new(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: &JS<Document>) - -> JS<DocumentType> { + document: &JSRef<Document>) + -> Temporary<DocumentType> { let documenttype = DocumentType::new_inherited(name, public_id, system_id, - document.clone()); + document); Node::reflect_node(~documenttype, document, DocumentTypeBinding::Wrap) } } -impl DocumentType { - pub fn Name(&self) -> DOMString { +pub trait DocumentTypeMethods { + fn Name(&self) -> DOMString; + fn PublicId(&self) -> DOMString; + fn SystemId(&self) -> DOMString; +} + +impl<'a> DocumentTypeMethods for JSRef<'a, DocumentType> { + fn Name(&self) -> DOMString { self.name.clone() } - pub fn PublicId(&self) -> DOMString { + fn PublicId(&self) -> DOMString { self.public_id.clone() } - pub fn SystemId(&self) -> DOMString { + fn SystemId(&self) -> DOMString { self.system_id.clone() } } diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs index 6bb946e4bed..d3ef0664383 100644 --- a/src/components/script/dom/domexception.rs +++ b/src/components/script/dom/domexception.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding; use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding::DOMExceptionConstants; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::str::DOMString; @@ -49,7 +49,7 @@ impl DOMException { } } - pub fn new(window: &JS<Window>, code: DOMErrorName) -> JS<DOMException> { + pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> Temporary<DOMException> { reflect_dom_object(~DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap) } } @@ -64,9 +64,15 @@ impl Reflectable for DOMException { } } -impl DOMException { +pub trait DOMExceptionMethods { + fn Code(&self) -> u16; + fn Name(&self) -> DOMString; + fn Message(&self) -> DOMString; +} + +impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> { // http://dom.spec.whatwg.org/#dom-domexception-code - pub fn Code(&self) -> u16 { + fn Code(&self) -> u16 { match self.code { // http://dom.spec.whatwg.org/#concept-throw EncodingError => 0, @@ -75,12 +81,12 @@ impl DOMException { } // http://dom.spec.whatwg.org/#error-names-0 - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { self.code.to_str() } // http://dom.spec.whatwg.org/#error-names-0 - pub fn Message(&self) -> DOMString { + fn Message(&self) -> DOMString { match self.code { IndexSizeError => ~"The index is not in the allowed range.", HierarchyRequestError => ~"The operation would yield an incorrect node tree.", diff --git a/src/components/script/dom/domimplementation.rs b/src/components/script/dom/domimplementation.rs index 28d226ba406..53cb09fba16 100644 --- a/src/components/script/dom/domimplementation.rs +++ b/src/components/script/dom/domimplementation.rs @@ -4,19 +4,19 @@ use dom::bindings::codegen::BindingDeclarations::DOMImplementationBinding; use dom::bindings::codegen::InheritTypes::NodeCast; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable}; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::error::{Fallible, InvalidCharacter, NamespaceError}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; -use dom::document::{Document, HTMLDocument, NonHTMLDocument}; +use dom::document::{Document, HTMLDocument, NonHTMLDocument, DocumentMethods}; use dom::documenttype::DocumentType; use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmltitleelement::HTMLTitleElement; -use dom::node::{Node, INode}; +use dom::node::{Node, NodeMethods}; use dom::text::Text; -use dom::window::Window; +use dom::window::{Window, WindowMethods}; use servo_util::str::DOMString; #[deriving(Encodable)] @@ -26,15 +26,15 @@ pub struct DOMImplementation { } impl DOMImplementation { - pub fn new_inherited(owner: JS<Window>) -> DOMImplementation { + pub fn new_inherited(owner: &JSRef<Window>) -> DOMImplementation { DOMImplementation { - owner: owner, + owner: owner.unrooted(), reflector_: Reflector::new(), } } - pub fn new(owner: &JS<Window>) -> JS<DOMImplementation> { - reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner, + pub fn new(owner: &JSRef<Window>) -> Temporary<DOMImplementation> { + reflect_dom_object(~DOMImplementation::new_inherited(owner), owner, DOMImplementationBinding::Wrap) } } @@ -49,102 +49,124 @@ impl Reflectable for DOMImplementation { } } +pub trait DOMImplementationMethods { + fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>>; + fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString, + mut maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<Temporary<Document>>; + fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Temporary<Document>; +} + // http://dom.spec.whatwg.org/#domimplementation -impl DOMImplementation { +impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype - pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<JS<DocumentType>> { + fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>> { match xml_name_type(qname) { // Step 1. InvalidXMLName => Err(InvalidCharacter), // Step 2. Name => Err(NamespaceError), // Step 3. - QName => Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &self.owner.get().Document())) + QName => { + let owner = self.owner.root(); + let document = owner.deref().Document().root(); + Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &*document)) + } } } // http://dom.spec.whatwg.org/#dom-domimplementation-createdocument - pub fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString, - maybe_doctype: Option<JS<DocumentType>>) -> Fallible<JS<Document>> { - // Step 1. - let doc = Document::new(&self.owner, None, NonHTMLDocument, None); - let mut doc_node: JS<Node> = NodeCast::from(&doc); + fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString, + mut maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<Temporary<Document>> { + let win = self.owner.root(); + // Step 1. + let mut doc = Document::new(&win.root_ref(), None, NonHTMLDocument, None).root(); // Step 2-3. - let maybe_elem = if qname.is_empty() { + let mut maybe_elem = if qname.is_empty() { None } else { - match doc.get().CreateElementNS(&doc, namespace, qname) { + match doc.CreateElementNS(namespace, qname) { Err(error) => return Err(error), Ok(elem) => Some(elem) } }; - // Step 4. - match maybe_doctype { - None => (), - Some(ref doctype) => assert!(doc_node.AppendChild(&mut NodeCast::from(doctype)).is_ok()) - } + { + let doc_node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *doc); - // Step 5. - match maybe_elem { - None => (), - Some(ref elem) => assert!(doc_node.AppendChild(&mut NodeCast::from(elem)).is_ok()) + // Step 4. + match maybe_doctype { + None => (), + Some(ref mut doctype) => { + assert!(doc_node.AppendChild(NodeCast::from_mut_ref(doctype)).is_ok()) + } + } + + // Step 5. + match maybe_elem.root() { + None => (), + Some(mut elem) => { + assert!(doc_node.AppendChild(NodeCast::from_mut_ref(&mut *elem)).is_ok()) + } + } } // Step 6. // FIXME: https://github.com/mozilla/servo/issues/1522 // Step 7. - Ok(doc) + Ok(Temporary::from_rooted(&*doc)) } // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument - pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> JS<Document> { + fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Temporary<Document> { + let owner = self.owner.root(); + // Step 1-2. - let doc = Document::new(&self.owner, None, HTMLDocument, None); - let mut doc_node: JS<Node> = NodeCast::from(&doc); + let mut doc = Document::new(&owner.root_ref(), None, HTMLDocument, None).root(); + let mut doc_alias = doc.clone(); + let doc_node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut doc_alias); { // Step 3. - let doc_type = DocumentType::new(~"html", None, None, &doc); - assert!(doc_node.AppendChild(&mut NodeCast::from(&doc_type)).is_ok()); + let mut doc_type = DocumentType::new(~"html", None, None, &*doc).root(); + assert!(doc_node.AppendChild(NodeCast::from_mut_ref(&mut *doc_type)).is_ok()); } { // Step 4. - let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc)); - assert!(doc_node.AppendChild(&mut doc_html).is_ok()); + let mut doc_html = NodeCast::from_unrooted(HTMLHtmlElement::new(~"html", &*doc)).root(); + assert!(doc_node.AppendChild(&mut *doc_html).is_ok()); { // Step 5. - let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc)); - assert!(doc_html.AppendChild(&mut doc_head).is_ok()); + let mut doc_head = NodeCast::from_unrooted(HTMLHeadElement::new(~"head", &*doc)).root(); + assert!(doc_html.AppendChild(&mut *doc_head).is_ok()); // Step 6. match title { None => (), Some(title_str) => { // Step 6.1. - let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc)); - assert!(doc_head.AppendChild(&mut doc_title).is_ok()); + let mut doc_title = NodeCast::from_unrooted(HTMLTitleElement::new(~"title", &*doc)).root(); + assert!(doc_head.AppendChild(&mut *doc_title).is_ok()); // Step 6.2. - let title_text = Text::new(title_str, &doc); - assert!(doc_title.AppendChild(&mut NodeCast::from(&title_text)).is_ok()); + let mut title_text = Text::new(title_str, &*doc).root(); + assert!(doc_title.AppendChild(NodeCast::from_mut_ref(&mut *title_text)).is_ok()); } } } // Step 7. - let doc_body = HTMLBodyElement::new(~"body", &doc); - assert!(doc_html.AppendChild(&mut NodeCast::from(&doc_body)).is_ok()); + let mut doc_body = HTMLBodyElement::new(~"body", &*doc).root(); + assert!(doc_html.AppendChild(NodeCast::from_mut_ref(&mut *doc_body)).is_ok()); } // Step 8. // FIXME: https://github.com/mozilla/servo/issues/1522 // Step 9. - doc + Temporary::from_rooted(&*doc) } } diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs index 1961c8d4661..db2714c642f 100644 --- a/src/components/script/dom/domparser.rs +++ b/src/components/script/dom/domparser.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::DOMParserBinding; use dom::bindings::codegen::BindingDeclarations::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::error::{Fallible, FailureUnknown}; use dom::document::{Document, HTMLDocument, NonHTMLDocument}; @@ -18,32 +18,40 @@ pub struct DOMParser { } impl DOMParser { - pub fn new_inherited(owner: JS<Window>) -> DOMParser { + pub fn new_inherited(owner: &JSRef<Window>) -> DOMParser { DOMParser { - owner: owner, + owner: owner.unrooted(), reflector_: Reflector::new() } } - pub fn new(owner: &JS<Window>) -> JS<DOMParser> { - reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner, + pub fn new(owner: &JSRef<Window>) -> Temporary<DOMParser> { + reflect_dom_object(~DOMParser::new_inherited(owner), owner, DOMParserBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DOMParser>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Temporary<DOMParser>> { Ok(DOMParser::new(owner)) } +} + +pub trait DOMParserMethods { + fn ParseFromString(&self, _s: DOMString, ty: DOMParserBinding::SupportedType) + -> Fallible<Temporary<Document>>; +} - pub fn ParseFromString(&self, - _s: DOMString, - ty: DOMParserBinding::SupportedType) - -> Fallible<JS<Document>> { +impl<'a> DOMParserMethods for JSRef<'a, DOMParser> { + fn ParseFromString(&self, + _s: DOMString, + ty: DOMParserBinding::SupportedType) + -> Fallible<Temporary<Document>> { + let owner = self.owner.root(); match ty { Text_html => { - Ok(Document::new(&self.owner, None, HTMLDocument, Some(~"text/html"))) + Ok(Document::new(&owner.root_ref(), None, HTMLDocument, Some(~"text/html"))) } Text_xml => { - Ok(Document::new(&self.owner, None, NonHTMLDocument, Some(~"text/xml"))) + Ok(Document::new(&owner.root_ref(), None, NonHTMLDocument, Some(~"text/xml"))) } _ => { Err(FailureUnknown) diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 4f1e265e8f9..751251584a7 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -4,21 +4,23 @@ //! Element nodes. -use dom::attr::{Attr, AttrSettingType, ReplacedAttr, FirstSetAttr}; +use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrMethods}; use dom::attrlist::AttrList; use dom::bindings::codegen::BindingDeclarations::ElementBinding; use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, TemporaryPushable}; +use dom::bindings::js::{OptionalSettable, OptionalRootable, Root}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::error::{ErrorResult, Fallible, NamespaceError, InvalidCharacter}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; use dom::clientrect::ClientRect; use dom::clientrectlist::ClientRectList; -use dom::document::Document; +use dom::document::{Document, DocumentHelpers}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; use dom::htmlserializer::serialize; use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node}; +use dom::node::{window_from_node, LayoutNodeHelpers}; use dom::virtualmethods::{VirtualMethods, vtable_for}; use layout_interface::ContentChangedDocumentDamage; use layout_interface::MatchSelectorsDocumentDamage; @@ -139,7 +141,7 @@ pub enum ElementTypeId { // impl Element { - pub fn new_inherited(type_id: ElementTypeId, local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: JS<Document>) -> Element { + pub fn new_inherited(type_id: ElementTypeId, local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JSRef<Document>) -> Element { Element { node: Node::new_inherited(ElementNodeTypeId(type_id), document), local_name: local_name, @@ -151,53 +153,65 @@ impl Element { } } - pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JS<Document>) -> JS<Element> { - let element = Element::new_inherited(ElementTypeId, local_name, namespace, prefix, document.clone()); + pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JSRef<Document>) -> Temporary<Element> { + let element = Element::new_inherited(ElementTypeId, local_name, namespace, prefix, document); Node::reflect_node(~element, document, ElementBinding::Wrap) } +} + +pub trait RawLayoutElementHelpers { + unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) -> Option<&'static str>; +} - pub fn html_element_in_html_document(&self) -> bool { - self.namespace == namespace::HTML && - self.node.owner_doc().get().is_html_document +impl RawLayoutElementHelpers for Element { + #[inline] + unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) + -> Option<&'static str> { + self.attrs.iter().find(|attr: & &JS<Attr>| { + let attr = attr.unsafe_get(); + name == (*attr).local_name && (*attr).namespace == *namespace + }).map(|attr| { + let attr = attr.unsafe_get(); + cast::transmute((*attr).value.as_slice()) + }) } } -impl Element { - pub unsafe fn html_element_in_html_document_for_layout(&self) -> bool { - if self.namespace != namespace::HTML { +pub trait LayoutElementHelpers { + unsafe fn html_element_in_html_document_for_layout(&self) -> bool; +} + +impl LayoutElementHelpers for JS<Element> { + unsafe fn html_element_in_html_document_for_layout(&self) -> bool { + if (*self.unsafe_get()).namespace != namespace::HTML { return false } - let owner_doc: *JS<Document> = self.node.owner_doc(); - let owner_doc: **Document = owner_doc as **Document; - (**owner_doc).is_html_document + let node: JS<Node> = self.transmute_copy(); + let owner_doc = node.owner_doc_for_layout().unsafe_get(); + (*owner_doc).is_html_document } +} - #[inline] - pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) - -> Option<&'static str> { - self.attrs.iter().find(|attr: & &JS<Attr>| { - // unsafely avoid a borrow because this is accessed by many tasks - // during parallel layout - let attr: ***Attr = cast::transmute(attr); - name == (***attr).local_name && (***attr).namespace == *namespace - }).map(|attr| { - let attr: **Attr = cast::transmute(attr); - cast::transmute((**attr).value.as_slice()) - }) +pub trait ElementHelpers { + fn html_element_in_html_document(&self) -> bool; +} + +impl<'a> ElementHelpers for JSRef<'a, Element> { + fn html_element_in_html_document(&self) -> bool { + let is_html = self.namespace == namespace::HTML; + let node: &JSRef<Node> = NodeCast::from_ref(self); + is_html && node.owner_doc().root().is_html_document } } pub trait AttributeHandlers { - fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>>; + fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>>; fn set_attr(&mut self, name: DOMString, value: DOMString) -> ErrorResult; fn set_attribute(&mut self, namespace: Namespace, name: DOMString, value: DOMString) -> ErrorResult; fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>, cb: |&JS<Attr>| -> bool); - fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult; - fn SetAttributeNS(&mut self, namespace_url: Option<DOMString>, - name: DOMString, value: DOMString) -> ErrorResult; + prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool); fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult; fn notify_attribute_changed(&self, local_name: DOMString); @@ -211,18 +225,16 @@ pub trait AttributeHandlers { fn set_uint_attribute(&mut self, name: &str, value: u32); } -impl AttributeHandlers for JS<Element> { - fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>> { - if self.get().html_element_in_html_document() { - self.get().attrs.iter().find(|attr| { - let attr = attr.get(); +impl<'a> AttributeHandlers for JSRef<'a, Element> { + fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>> { + if self.html_element_in_html_document() { + self.deref().attrs.iter().map(|attr| attr.root()).find(|attr| { name.to_ascii_lower() == attr.local_name && attr.namespace == namespace - }).map(|x| x.clone()) + }).map(|x| Temporary::from_rooted(&*x)) } else { - self.get().attrs.iter().find(|attr| { - let attr = attr.get(); + self.deref().attrs.iter().map(|attr| attr.root()).find(|attr| { name == attr.local_name && attr.namespace == namespace - }).map(|x| x.clone()) + }).map(|x| Temporary::from_rooted(&*x)) } } @@ -244,14 +256,15 @@ impl AttributeHandlers for JS<Element> { None => {} } - let node: JS<Node> = NodeCast::from(self); - node.get().wait_until_safe_to_modify_dom(); + let self_alias = self.clone(); + let node: &JSRef<Node> = NodeCast::from_ref(&self_alias); + node.wait_until_safe_to_modify_dom(); - let position: |&JS<Attr>| -> bool = - if self.get().html_element_in_html_document() { - |attr| attr.get().local_name.eq_ignore_ascii_case(local_name) + let position: |&JSRef<Attr>| -> bool = + if self.html_element_in_html_document() { + |attr| attr.deref().local_name.eq_ignore_ascii_case(local_name) } else { - |attr| attr.get().local_name == local_name + |attr| attr.deref().local_name == local_name }; self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, position); Ok(()) @@ -259,128 +272,46 @@ impl AttributeHandlers for JS<Element> { fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>, cb: |&JS<Attr>| -> bool) { - let node: JS<Node> = NodeCast::from(self); - let idx = self.get().attrs.iter().position(cb); - let (mut attr, set_type): (JS<Attr>, AttrSettingType) = match idx { - Some(idx) => { - let attr = self.get_mut().attrs.get(idx).clone(); - (attr, ReplacedAttr) - } - + prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) { + let idx = self.deref().attrs.iter() + .map(|attr| attr.root()) + .position(|attr| cb(&*attr)); + let (idx, set_type) = match idx { + Some(idx) => (idx, ReplacedAttr), None => { - let doc = node.get().owner_doc().get(); - let attr = Attr::new(&doc.window, local_name.clone(), value.clone(), - name, namespace.clone(), prefix, self.clone()); - self.get_mut().attrs.push(attr.clone()); - (attr, FirstSetAttr) + let window = window_from_node(self).root(); + let attr = Attr::new(&*window, local_name.clone(), value.clone(), + name, namespace.clone(), prefix, self); + self.deref_mut().attrs.push_unrooted(&attr); + (self.deref().attrs.len() - 1, FirstSetAttr) } }; - attr.get_mut().set_value(set_type, value); - } - - // http://dom.spec.whatwg.org/#dom-element-setattribute - fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult { - let node: JS<Node> = NodeCast::from(self); - node.get().wait_until_safe_to_modify_dom(); - - // Step 1. - match xml_name_type(name) { - InvalidXMLName => return Err(InvalidCharacter), - _ => {} - } - - // Step 2. - let name = if self.get().html_element_in_html_document() { - name.to_ascii_lower() - } else { - name - }; - - // Step 3-5. - self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| { - attr.get().name == name - }); - Ok(()) - } - - fn SetAttributeNS(&mut self, namespace_url: Option<DOMString>, - name: DOMString, value: DOMString) -> ErrorResult { - let node: JS<Node> = NodeCast::from(self); - node.get().wait_until_safe_to_modify_dom(); - - // Step 1. - let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); - - let name_type = xml_name_type(name); - match name_type { - // Step 2. - InvalidXMLName => return Err(InvalidCharacter), - // Step 3. - Name => return Err(NamespaceError), - QName => {} - } - - // Step 4. - let (prefix, local_name) = get_attribute_parts(name.clone()); - match prefix { - Some(ref prefix_str) => { - // Step 5. - if namespace == namespace::Null { - return Err(NamespaceError); - } - - // Step 6. - if "xml" == prefix_str.as_slice() && namespace != namespace::XML { - return Err(NamespaceError); - } - - // Step 7b. - if "xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS { - return Err(NamespaceError); - } - }, - None => {} - } - - // Step 7a. - if "xmlns" == name && namespace != namespace::XMLNS { - return Err(NamespaceError); - } - - // Step 8. - if namespace == namespace::XMLNS && "xmlns" != name && Some(~"xmlns") != prefix { - return Err(NamespaceError); - } - - // Step 9. - self.do_set_attribute(local_name.clone(), value, name, namespace.clone(), prefix, |attr| { - attr.get().local_name == local_name && - attr.get().namespace == namespace - }); - Ok(()) + self.deref_mut().attrs.get(idx).root().set_value(set_type, value); } fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult { let (_, local_name) = get_attribute_parts(name.clone()); - let node: JS<Node> = NodeCast::from(self); - node.get().wait_until_safe_to_modify_dom(); - - let idx = self.get().attrs.iter().position(|attr| { - attr.get().local_name == local_name + let idx = self.deref().attrs.iter().map(|attr| attr.root()).position(|attr| { + attr.local_name == local_name }); match idx { None => (), Some(idx) => { + { + let node: &mut JSRef<Node> = NodeCast::from_mut_ref(self); + node.wait_until_safe_to_modify_dom(); + } + if namespace == namespace::Null { - let removed_raw_value = self.get().attrs.get(idx).get().Value(); - vtable_for(&node).before_remove_attr(local_name.clone(), removed_raw_value); + let removed_raw_value = self.deref().attrs.get(idx).root().Value(); + vtable_for(NodeCast::from_mut_ref(self)) + .before_remove_attr(local_name.clone(), removed_raw_value); } - self.get_mut().attrs.remove(idx); + self.deref_mut().attrs.remove(idx); } }; @@ -388,14 +319,14 @@ impl AttributeHandlers for JS<Element> { } fn notify_attribute_changed(&self, local_name: DOMString) { - let node: JS<Node> = NodeCast::from(self); + let node: &JSRef<Node> = NodeCast::from_ref(self); if node.is_in_doc() { let damage = match local_name.as_slice() { "style" | "id" | "class" => MatchSelectorsDocumentDamage, _ => ContentChangedDocumentDamage }; - let document = node.get().owner_doc(); - document.get().damage_and_reflow(damage); + let document = node.owner_doc().root(); + document.deref().damage_and_reflow(damage); } } @@ -415,7 +346,10 @@ impl AttributeHandlers for JS<Element> { fn get_string_attribute(&self, name: &str) -> DOMString { match self.get_attribute(Null, name) { - Some(x) => x.get().Value(), + Some(x) => { + let x = x.root(); + x.deref().Value() + } None => ~"" } } @@ -446,23 +380,51 @@ impl Element { } } -impl Element { +pub trait ElementMethods { + fn NamespaceURI(&self) -> DOMString; + fn LocalName(&self) -> DOMString; + fn GetPrefix(&self) -> Option<DOMString>; + fn TagName(&self) -> DOMString; + fn Id(&self) -> DOMString; + fn SetId(&mut self, id: DOMString); + fn ClassName(&self) -> DOMString; + fn SetClassName(&mut self, class: DOMString); + fn Attributes(&mut self) -> Temporary<AttrList>; + fn GetAttribute(&self, name: DOMString) -> Option<DOMString>; + fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString>; + fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult; + fn SetAttributeNS(&mut self, namespace_url: Option<DOMString>, name: DOMString, value: DOMString) -> ErrorResult; + fn RemoveAttribute(&mut self, name: DOMString) -> ErrorResult; + fn RemoveAttributeNS(&mut self, namespace: Option<DOMString>, localname: DOMString) -> ErrorResult; + fn HasAttribute(&self, name: DOMString) -> bool; + fn HasAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> bool; + fn GetElementsByTagName(&self, localname: DOMString) -> Temporary<HTMLCollection>; + fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, localname: DOMString) -> Temporary<HTMLCollection>; + fn GetElementsByClassName(&self, classes: DOMString) -> Temporary<HTMLCollection>; + fn GetClientRects(&self) -> Temporary<ClientRectList>; + fn GetBoundingClientRect(&self) -> Temporary<ClientRect>; + fn GetInnerHTML(&self) -> Fallible<DOMString>; + fn GetOuterHTML(&self) -> Fallible<DOMString>; + fn Children(&self) -> Temporary<HTMLCollection>; +} + +impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-namespaceuri - pub fn NamespaceURI(&self) -> DOMString { + fn NamespaceURI(&self) -> DOMString { self.namespace.to_str().to_owned() } - pub fn LocalName(&self) -> DOMString { + fn LocalName(&self) -> DOMString { self.local_name.clone() } // http://dom.spec.whatwg.org/#dom-element-prefix - pub fn GetPrefix(&self) -> Option<DOMString> { + fn GetPrefix(&self) -> Option<DOMString> { self.prefix.clone() } // http://dom.spec.whatwg.org/#dom-element-tagname - pub fn TagName(&self) -> DOMString { + fn TagName(&self) -> DOMString { match self.prefix { None => { self.local_name.to_ascii_upper() @@ -474,176 +436,247 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-id - pub fn Id(&self, abstract_self: &JS<Element>) -> DOMString { - abstract_self.get_string_attribute("id") + fn Id(&self) -> DOMString { + self.get_string_attribute("id") } // http://dom.spec.whatwg.org/#dom-element-id - pub fn SetId(&mut self, abstract_self: &mut JS<Element>, id: DOMString) { - abstract_self.set_string_attribute("id", id); + fn SetId(&mut self, id: DOMString) { + self.set_string_attribute("id", id); } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn ClassName(&self, abstract_self: &JS<Element>) -> DOMString { - abstract_self.get_string_attribute("class") + fn ClassName(&self) -> DOMString { + self.get_string_attribute("class") } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn SetClassName(&self, abstract_self: &mut JS<Element>, class: DOMString) { - abstract_self.set_string_attribute("class", class); + fn SetClassName(&mut self, class: DOMString) { + self.set_string_attribute("class", class); } // http://dom.spec.whatwg.org/#dom-element-attributes - pub fn Attributes(&mut self, abstract_self: &JS<Element>) -> JS<AttrList> { + fn Attributes(&mut self) -> Temporary<AttrList> { match self.attr_list { - None => { - let doc = self.node.owner_doc(); - let doc = doc.get(); - let list = AttrList::new(&doc.window, abstract_self); - self.attr_list = Some(list.clone()); - list - } - Some(ref list) => list.clone() + None => (), + Some(ref list) => return Temporary::new(list.clone()), } + + let doc = { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.owner_doc().root() + }; + let window = doc.deref().window.root(); + let list = AttrList::new(&*window, self); + self.attr_list.assign(Some(list)); + Temporary::new(self.attr_list.get_ref().clone()) } // http://dom.spec.whatwg.org/#dom-element-getattribute - pub fn GetAttribute(&self, abstract_self: &JS<Element>, name: DOMString) -> Option<DOMString> { - let name = if abstract_self.get().html_element_in_html_document() { + fn GetAttribute(&self, name: DOMString) -> Option<DOMString> { + let name = if self.html_element_in_html_document() { name.to_ascii_lower() } else { name }; - abstract_self.get_attribute(Null, name).map(|s| s.get().Value()) + self.get_attribute(Null, name).root() + .map(|s| s.deref().Value()) } // http://dom.spec.whatwg.org/#dom-element-getattributens - pub fn GetAttributeNS(&self, abstract_self: &JS<Element>, - namespace: Option<DOMString>, - local_name: DOMString) -> Option<DOMString> { + fn GetAttributeNS(&self, + namespace: Option<DOMString>, + local_name: DOMString) -> Option<DOMString> { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - abstract_self.get_attribute(namespace, local_name) - .map(|attr| attr.get().value.clone()) + self.get_attribute(namespace, local_name).root() + .map(|attr| attr.deref().Value()) } // http://dom.spec.whatwg.org/#dom-element-setattribute - pub fn SetAttribute(&self, abstract_self: &mut JS<Element>, - name: DOMString, - value: DOMString) -> ErrorResult { - abstract_self.SetAttribute(name, value) + fn SetAttribute(&mut self, + name: DOMString, + value: DOMString) -> ErrorResult { + { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.wait_until_safe_to_modify_dom(); + } + + // Step 1. + match xml_name_type(name) { + InvalidXMLName => return Err(InvalidCharacter), + _ => {} + } + + // Step 2. + let name = if self.html_element_in_html_document() { + name.to_ascii_lower() + } else { + name + }; + + // Step 3-5. + self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| { + attr.deref().name == name + }); + Ok(()) } // http://dom.spec.whatwg.org/#dom-element-setattributens - pub fn SetAttributeNS(&self, - abstract_self: &mut JS<Element>, - namespace_url: Option<DOMString>, - name: DOMString, - value: DOMString) -> ErrorResult { - abstract_self.SetAttributeNS(namespace_url, name, value) + fn SetAttributeNS(&mut self, + namespace_url: Option<DOMString>, + name: DOMString, + value: DOMString) -> ErrorResult { + { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.wait_until_safe_to_modify_dom(); + } + + // Step 1. + let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); + + let name_type = xml_name_type(name); + match name_type { + // Step 2. + InvalidXMLName => return Err(InvalidCharacter), + // Step 3. + Name => return Err(NamespaceError), + QName => {} + } + + // Step 4. + let (prefix, local_name) = get_attribute_parts(name.clone()); + match prefix { + Some(ref prefix_str) => { + // Step 5. + if namespace == namespace::Null { + return Err(NamespaceError); + } + + // Step 6. + if "xml" == prefix_str.as_slice() && namespace != namespace::XML { + return Err(NamespaceError); + } + + // Step 7b. + if "xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS { + return Err(NamespaceError); + } + }, + None => {} + } + + // Step 7a. + if "xmlns" == name && namespace != namespace::XMLNS { + return Err(NamespaceError); + } + + // Step 8. + if namespace == namespace::XMLNS && "xmlns" != name && Some(~"xmlns") != prefix { + return Err(NamespaceError); + } + + // Step 9. + self.do_set_attribute(local_name.clone(), value, name, namespace.clone(), prefix, |attr| { + attr.deref().local_name == local_name && + attr.deref().namespace == namespace + }); + Ok(()) } // http://dom.spec.whatwg.org/#dom-element-removeattribute - pub fn RemoveAttribute(&mut self, - abstract_self: &mut JS<Element>, - name: DOMString) -> ErrorResult { + fn RemoveAttribute(&mut self, + name: DOMString) -> ErrorResult { let name = if self.html_element_in_html_document() { name.to_ascii_lower() } else { name }; - abstract_self.remove_attribute(namespace::Null, name) + self.remove_attribute(namespace::Null, name) } // http://dom.spec.whatwg.org/#dom-element-removeattributens - pub fn RemoveAttributeNS(&mut self, - abstract_self: &mut JS<Element>, - namespace: Option<DOMString>, - localname: DOMString) -> ErrorResult { + fn RemoveAttributeNS(&mut self, + namespace: Option<DOMString>, + localname: DOMString) -> ErrorResult { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - abstract_self.remove_attribute(namespace, localname) + self.remove_attribute(namespace, localname) } // http://dom.spec.whatwg.org/#dom-element-hasattribute - pub fn HasAttribute(&self, abstract_self: &JS<Element>, - name: DOMString) -> bool { - self.GetAttribute(abstract_self, name).is_some() + fn HasAttribute(&self, + name: DOMString) -> bool { + self.GetAttribute(name).is_some() } // http://dom.spec.whatwg.org/#dom-element-hasattributens - pub fn HasAttributeNS(&self, abstract_self: &JS<Element>, - namespace: Option<DOMString>, - local_name: DOMString) -> bool { - self.GetAttributeNS(abstract_self, namespace, local_name).is_some() + fn HasAttributeNS(&self, + namespace: Option<DOMString>, + local_name: DOMString) -> bool { + self.GetAttributeNS(namespace, local_name).is_some() } - pub fn GetElementsByTagName(&self, abstract_self: &JS<Element>, localname: DOMString) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::by_tag_name(&doc.window, &NodeCast::from(abstract_self), localname) + fn GetElementsByTagName(&self, localname: DOMString) -> Temporary<HTMLCollection> { + let window = window_from_node(self).root(); + HTMLCollection::by_tag_name(&*window, NodeCast::from_ref(self), localname) } - pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<Element>, maybe_ns: Option<DOMString>, - localname: DOMString) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); + fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, + localname: DOMString) -> Temporary<HTMLCollection> { let namespace = match maybe_ns { Some(namespace) => Namespace::from_str(namespace), None => Null }; - HTMLCollection::by_tag_name_ns(&doc.window, &NodeCast::from(abstract_self), localname, namespace) + let window = window_from_node(self).root(); + HTMLCollection::by_tag_name_ns(&*window, NodeCast::from_ref(self), localname, namespace) } - pub fn GetElementsByClassName(&self, abstract_self: &JS<Element>, classes: DOMString) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::by_class_name(&doc.window, &NodeCast::from(abstract_self), classes) + fn GetElementsByClassName(&self, classes: DOMString) -> Temporary<HTMLCollection> { + let window = window_from_node(self).root(); + HTMLCollection::by_class_name(&*window, NodeCast::from_ref(self), classes) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects - pub fn GetClientRects(&self, abstract_self: &JS<Element>) -> JS<ClientRectList> { - let doc = self.node.owner_doc(); - let win = &doc.get().window; - let node: JS<Node> = NodeCast::from(abstract_self); + fn GetClientRects(&self) -> Temporary<ClientRectList> { + let win = window_from_node(self).root(); + let node: &JSRef<Node> = NodeCast::from_ref(self); let rects = node.get_content_boxes(); - let rects = rects.iter().map(|r| { + let rects: ~[Root<ClientRect>] = rects.iter().map(|r| { ClientRect::new( - win, + &*win, r.origin.y, r.origin.y + r.size.height, r.origin.x, - r.origin.x + r.size.width) + r.origin.x + r.size.width).root() }).collect(); - ClientRectList::new(win, rects) + ClientRectList::new(&*win, rects.iter().map(|rect| rect.deref().clone()).collect()) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect - pub fn GetBoundingClientRect(&self, abstract_self: &JS<Element>) -> JS<ClientRect> { - let doc = self.node.owner_doc(); - let win = &doc.get().window; - let node: JS<Node> = NodeCast::from(abstract_self); + fn GetBoundingClientRect(&self) -> Temporary<ClientRect> { + let win = window_from_node(self).root(); + let node: &JSRef<Node> = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); ClientRect::new( - win, + &*win, rect.origin.y, rect.origin.y + rect.size.height, rect.origin.x, rect.origin.x + rect.size.width) } - pub fn GetInnerHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { + fn GetInnerHTML(&self) -> Fallible<DOMString> { //XXX TODO: XML case - Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), false, false))) + Ok(serialize(&mut NodeIterator::new(NodeCast::from_ref(self), false, false))) } - pub fn GetOuterHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { - Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), true, false))) + fn GetOuterHTML(&self) -> Fallible<DOMString> { + Ok(serialize(&mut NodeIterator::new(NodeCast::from_ref(self), true, false))) } - pub fn Children(&self, abstract_self: &JS<Element>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) + fn Children(&self) -> Temporary<HTMLCollection> { + let window = window_from_node(self).root(); + HTMLCollection::children(&*window, NodeCast::from_ref(self)) } } @@ -660,10 +693,10 @@ pub fn get_attribute_parts(name: DOMString) -> (Option<~str>, ~str) { (prefix, local_name) } -impl VirtualMethods for JS<Element> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let node: JS<Node> = NodeCast::from(self); - Some(~node as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, Element> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let node: &mut JSRef<Node> = NodeCast::from_mut_ref(self); + Some(node as &mut VirtualMethods:) } fn after_set_attr(&mut self, name: DOMString, value: DOMString) { @@ -672,19 +705,18 @@ impl VirtualMethods for JS<Element> { _ => (), } - let node: JS<Node> = NodeCast::from(self); match name.as_slice() { "style" => { - let doc = node.get().owner_doc(); - let base_url = doc.get().url().clone(); - self.get_mut().style_attribute = Some(style::parse_style_attribute(value, &base_url)) + let doc = document_from_node(self).root(); + let base_url = doc.deref().url().clone(); + self.deref_mut().style_attribute = Some(style::parse_style_attribute(value, &base_url)) } - "id" if node.is_in_doc() => { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let mut doc = node.get().owner_doc().clone(); - let doc = doc.get_mut(); - doc.register_named_element(self, value.clone()); + "id" => { + let node: &JSRef<Node> = NodeCast::from_ref(self); + if node.is_in_doc() { + let mut doc = document_from_node(self).root(); + doc.register_named_element(self, value.clone()); + } } _ => () } @@ -698,17 +730,16 @@ impl VirtualMethods for JS<Element> { _ => (), } - let node: JS<Node> = NodeCast::from(self); match name.as_slice() { "style" => { - self.get_mut().style_attribute = None + self.deref_mut().style_attribute = None } - "id" if node.is_in_doc() => { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let mut doc = node.get().owner_doc().clone(); - let doc = doc.get_mut(); - doc.unregister_named_element(self, value); + "id" => { + let node: &JSRef<Node> = NodeCast::from_ref(self); + if node.is_in_doc() { + let mut doc = document_from_node(self).root(); + doc.unregister_named_element(self, value); + } } _ => () } @@ -722,10 +753,10 @@ impl VirtualMethods for JS<Element> { _ => (), } - match self.get_attribute(Null, "id") { + match self.get_attribute(Null, "id").root() { Some(attr) => { - let mut doc = document_from_node(self); - doc.get_mut().register_named_element(self, attr.get().Value()); + let mut doc = document_from_node(self).root(); + doc.register_named_element(self, attr.deref().Value()); } _ => () } @@ -737,10 +768,10 @@ impl VirtualMethods for JS<Element> { _ => (), } - match self.get_attribute(Null, "id") { + match self.get_attribute(Null, "id").root() { Some(attr) => { - let mut doc = document_from_node(self); - doc.get_mut().unregister_named_element(self, attr.get().Value()); + let mut doc = document_from_node(self).root(); + doc.unregister_named_element(self, attr.deref().Value()); } _ => () } diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs index 22be9c3def0..260cf319201 100644 --- a/src/components/script/dom/event.rs +++ b/src/components/script/dom/event.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::EventBinding; use dom::bindings::codegen::BindingDeclarations::EventBinding::EventConstants; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::eventtarget::EventTarget; @@ -80,63 +80,89 @@ impl Event { } } - pub fn new(window: &JS<Window>) -> JS<Event> { + pub fn new(window: &JSRef<Window>) -> Temporary<Event> { reflect_dom_object(~Event::new_inherited(HTMLEventTypeId), window, EventBinding::Wrap) } - pub fn EventPhase(&self) -> u16 { + pub fn Constructor(global: &JSRef<Window>, + type_: DOMString, + init: &EventBinding::EventInit) -> Fallible<Temporary<Event>> { + let mut ev = Event::new(global).root(); + ev.InitEvent(type_, init.bubbles, init.cancelable); + Ok(Temporary::from_rooted(&*ev)) + } +} + +pub trait EventMethods { + fn EventPhase(&self) -> u16; + fn Type(&self) -> DOMString; + fn GetTarget(&self) -> Option<Temporary<EventTarget>>; + fn GetCurrentTarget(&self) -> Option<Temporary<EventTarget>>; + fn DefaultPrevented(&self) -> bool; + fn PreventDefault(&mut self); + fn StopPropagation(&mut self); + fn StopImmediatePropagation(&mut self); + fn Bubbles(&self) -> bool; + fn Cancelable(&self) -> bool; + fn TimeStamp(&self) -> u64; + fn InitEvent(&mut self, type_: DOMString, bubbles: bool, cancelable: bool); + fn IsTrusted(&self) -> bool; +} + +impl<'a> EventMethods for JSRef<'a, Event> { + fn EventPhase(&self) -> u16 { self.phase as u16 } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { self.type_.clone() } - pub fn GetTarget(&self) -> Option<JS<EventTarget>> { - self.target.clone() + fn GetTarget(&self) -> Option<Temporary<EventTarget>> { + self.target.as_ref().map(|target| Temporary::new(target.clone())) } - pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> { - self.current_target.clone() + fn GetCurrentTarget(&self) -> Option<Temporary<EventTarget>> { + self.current_target.as_ref().map(|target| Temporary::new(target.clone())) } - pub fn DefaultPrevented(&self) -> bool { + fn DefaultPrevented(&self) -> bool { self.canceled } - pub fn PreventDefault(&mut self) { + fn PreventDefault(&mut self) { if self.cancelable { self.canceled = true } } - pub fn StopPropagation(&mut self) { + fn StopPropagation(&mut self) { self.stop_propagation = true; } - pub fn StopImmediatePropagation(&mut self) { + fn StopImmediatePropagation(&mut self) { self.stop_immediate = true; self.stop_propagation = true; } - pub fn Bubbles(&self) -> bool { + fn Bubbles(&self) -> bool { self.bubbles } - pub fn Cancelable(&self) -> bool { + fn Cancelable(&self) -> bool { self.cancelable } - pub fn TimeStamp(&self) -> u64 { + fn TimeStamp(&self) -> u64 { self.timestamp } - pub fn InitEvent(&mut self, - type_: DOMString, - bubbles: bool, - cancelable: bool) { + fn InitEvent(&mut self, + type_: DOMString, + bubbles: bool, + cancelable: bool) { self.initialized = true; if self.dispatching { return; @@ -151,17 +177,9 @@ impl Event { self.cancelable = cancelable; } - pub fn IsTrusted(&self) -> bool { + fn IsTrusted(&self) -> bool { self.trusted } - - pub fn Constructor(global: &JS<Window>, - type_: DOMString, - init: &EventBinding::EventInit) -> Fallible<JS<Event>> { - let mut ev = Event::new(global); - ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable); - Ok(ev) - } } impl Reflectable for Event { diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs index d298ab38492..1bd90f93137 100644 --- a/src/components/script/dom/eventdispatcher.rs +++ b/src/components/script/dom/eventdispatcher.rs @@ -4,58 +4,59 @@ use dom::bindings::callback::ReportExceptions; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, OptionalSettable, Root}; use dom::eventtarget::{Capturing, Bubbling, EventTarget}; -use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing}; +use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing, EventMethods}; use dom::node::{Node, NodeHelpers}; // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm -pub fn dispatch_event(target: &JS<EventTarget>, - pseudo_target: Option<JS<EventTarget>>, - event: &mut JS<Event>) -> bool { - assert!(!event.get().dispatching); +pub fn dispatch_event<'a, 'b>(target: &JSRef<'a, EventTarget>, + pseudo_target: Option<JSRef<'b, EventTarget>>, + event: &mut JSRef<Event>) -> bool { + assert!(!event.deref().dispatching); { - let event = event.get_mut(); - event.target = pseudo_target.or_else(|| { - Some(target.clone()) - }); + let event = event.deref_mut(); + event.target.assign(Some(match pseudo_target { + Some(pseudo_target) => pseudo_target, + None => target.clone(), + })); event.dispatching = true; } - let type_ = event.get().type_.clone(); + let type_ = event.deref().type_.clone(); //TODO: no chain if not participating in a tree - let chain: Vec<JS<EventTarget>> = if target.get().is_node() { - let target_node: JS<Node> = NodeCast::to(target).unwrap(); + let mut chain: Vec<Root<EventTarget>> = if target.deref().is_node() { + let target_node: &JSRef<Node> = NodeCast::to_ref(target).unwrap(); target_node.ancestors().map(|ancestor| { - let ancestor_target: JS<EventTarget> = EventTargetCast::from(&ancestor); - ancestor_target + let ancestor_target: &JSRef<EventTarget> = EventTargetCast::from_ref(&ancestor); + ancestor_target.unrooted().root() }).collect() } else { vec!() }; - event.get_mut().phase = PhaseCapturing; + event.deref_mut().phase = PhaseCapturing; //FIXME: The "callback this value" should be currentTarget /* capturing */ for cur_target in chain.as_slice().rev_iter() { - let stopped = match cur_target.get().get_listeners_for(type_, Capturing) { + let stopped = match cur_target.get_listeners_for(type_, Capturing) { Some(listeners) => { - event.get_mut().current_target = Some(cur_target.clone()); + event.current_target.assign(Some(cur_target.deref().clone())); for listener in listeners.iter() { //FIXME: this should have proper error handling, or explicitly // drop the exception on the floor assert!(listener.HandleEvent__(event, ReportExceptions).is_ok()); - if event.get().stop_immediate { + if event.deref().stop_immediate { break; } } - event.get().stop_propagation + event.deref().stop_propagation } None => false }; @@ -66,20 +67,20 @@ pub fn dispatch_event(target: &JS<EventTarget>, } /* at target */ - if !event.get().stop_propagation { + if !event.deref().stop_propagation { { - let event = event.get_mut(); + let event = event.deref_mut(); event.phase = PhaseAtTarget; - event.current_target = Some(target.clone()); + event.current_target.assign(Some(target.clone())); } - let opt_listeners = target.get().get_listeners(type_); + let opt_listeners = target.deref().get_listeners(type_); for listeners in opt_listeners.iter() { for listener in listeners.iter() { //FIXME: this should have proper error handling, or explicitly drop the // exception on the floor. assert!(listener.HandleEvent__(event, ReportExceptions).is_ok()); - if event.get().stop_immediate { + if event.deref().stop_immediate { break; } } @@ -87,24 +88,24 @@ pub fn dispatch_event(target: &JS<EventTarget>, } /* bubbling */ - if event.get().bubbles && !event.get().stop_propagation { - event.get_mut().phase = PhaseBubbling; + if event.deref().bubbles && !event.deref().stop_propagation { + event.deref_mut().phase = PhaseBubbling; for cur_target in chain.iter() { - let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) { + let stopped = match cur_target.deref().get_listeners_for(type_, Bubbling) { Some(listeners) => { - event.get_mut().current_target = Some(cur_target.clone()); + event.deref_mut().current_target.assign(Some(cur_target.deref().clone())); for listener in listeners.iter() { //FIXME: this should have proper error handling or explicitly // drop exceptions on the floor. assert!(listener.HandleEvent__(event, ReportExceptions).is_ok()); - if event.get().stop_immediate { + if event.deref().stop_immediate { break; } } - event.get().stop_propagation + event.deref().stop_propagation } None => false }; @@ -114,7 +115,12 @@ pub fn dispatch_event(target: &JS<EventTarget>, } } - let event = event.get_mut(); + // Root ordering restrictions mean we need to unroot the chain entries + // in the same order they were rooted. + while chain.len() > 0 { + let _ = chain.pop(); + } + event.dispatching = false; event.phase = PhaseNone; event.current_target = None; diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs index 5214aa0aa69..17c8e19b45c 100644 --- a/src/components/script/dom/eventtarget.rs +++ b/src/components/script/dom/eventtarget.rs @@ -2,7 +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::bindings::js::JS; +use dom::bindings::js::JSRef; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::error::{Fallible, InvalidState}; use dom::bindings::codegen::BindingDeclarations::EventListenerBinding; @@ -64,11 +64,42 @@ impl EventTarget { filtered.map(|entry| entry.listener).collect() }) } +} + +pub trait EventTargetHelpers { + fn dispatch_event_with_target<'a>(&self, + target: Option<JSRef<'a, EventTarget>>, + event: &mut JSRef<Event>) -> Fallible<bool>; +} + +impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { + fn dispatch_event_with_target<'b>(&self, + target: Option<JSRef<'b, EventTarget>>, + event: &mut JSRef<Event>) -> Fallible<bool> { + if event.deref().dispatching || !event.deref().initialized { + return Err(InvalidState); + } + Ok(dispatch_event(self, target, event)) + } +} + +pub trait EventTargetMethods { + fn AddEventListener(&mut self, + ty: DOMString, + listener: Option<EventListener>, + capture: bool); + fn RemoveEventListener(&mut self, + ty: DOMString, + listener: Option<EventListener>, + capture: bool); + fn DispatchEvent(&self, event: &mut JSRef<Event>) -> Fallible<bool>; +} - pub fn AddEventListener(&mut self, - ty: DOMString, - listener: Option<EventListener>, - capture: bool) { +impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { + fn AddEventListener(&mut self, + ty: DOMString, + listener: Option<EventListener>, + capture: bool) { for &listener in listener.iter() { let entry = self.handlers.find_or_insert_with(ty.clone(), |_| vec!()); let phase = if capture { Capturing } else { Bubbling }; @@ -82,10 +113,10 @@ impl EventTarget { } } - pub fn RemoveEventListener(&mut self, - ty: DOMString, - listener: Option<EventListener>, - capture: bool) { + fn RemoveEventListener(&mut self, + ty: DOMString, + listener: Option<EventListener>, + capture: bool) { for &listener in listener.iter() { let mut entry = self.handlers.find_mut(&ty); for entry in entry.mut_iter() { @@ -102,19 +133,8 @@ impl EventTarget { } } - pub fn DispatchEvent(&self, abstract_self: &JS<EventTarget>, - event: &mut JS<Event>) -> Fallible<bool> { - self.dispatch_event_with_target(abstract_self, None, event) - } - - pub fn dispatch_event_with_target(&self, - abstract_self: &JS<EventTarget>, - abstract_target: Option<JS<EventTarget>>, - event: &mut JS<Event>) -> Fallible<bool> { - if event.get().dispatching || !event.get().initialized { - return Err(InvalidState); - } - Ok(dispatch_event(abstract_self, abstract_target, event)) + fn DispatchEvent(&self, event: &mut JSRef<Event>) -> Fallible<bool> { + self.dispatch_event_with_target(None, event) } } @@ -128,8 +148,8 @@ impl Reflectable for EventTarget { } } -impl VirtualMethods for JS<EventTarget> { - fn super_type(&self) -> Option<~VirtualMethods:> { +impl<'a> VirtualMethods for JSRef<'a, EventTarget> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { None } } diff --git a/src/components/script/dom/formdata.rs b/src/components/script/dom/formdata.rs index 140c70a12d2..c6631699671 100644 --- a/src/components/script/dom/formdata.rs +++ b/src/components/script/dom/formdata.rs @@ -5,7 +5,7 @@ use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{Fallible}; use dom::bindings::codegen::BindingDeclarations::FormDataBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalUnrootable}; use dom::blob::Blob; use dom::htmlformelement::HTMLFormElement; use dom::window::Window; @@ -28,33 +28,39 @@ pub struct FormData { } impl FormData { - pub fn new_inherited(form: Option<JS<HTMLFormElement>>, window: JS<Window>) -> FormData { + pub fn new_inherited(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> FormData { FormData { data: HashMap::new(), reflector_: Reflector::new(), - window: window, - form: form + window: window.unrooted(), + form: form.unrooted(), } } - pub fn new(form: Option<JS<HTMLFormElement>>, window: &JS<Window>) -> JS<FormData> { - reflect_dom_object(~FormData::new_inherited(form, window.clone()), window, FormDataBinding::Wrap) + pub fn new(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> Temporary<FormData> { + reflect_dom_object(~FormData::new_inherited(form, window), window, FormDataBinding::Wrap) } - pub fn Constructor(window: &JS<Window>, form: Option<JS<HTMLFormElement>>) - -> Fallible<JS<FormData>> { + pub fn Constructor(window: &JSRef<Window>, form: Option<JSRef<HTMLFormElement>>) -> Fallible<Temporary<FormData>> { Ok(FormData::new(form, window)) } +} + +pub trait FormDataMethods { + fn Append(&mut self, name: DOMString, value: &JSRef<Blob>, filename: Option<DOMString>); + fn Append_(&mut self, name: DOMString, value: DOMString); +} - pub fn Append(&mut self, name: DOMString, value: &JS<Blob>, filename: Option<DOMString>) { +impl<'a> FormDataMethods for JSRef<'a, FormData> { + fn Append(&mut self, name: DOMString, value: &JSRef<Blob>, filename: Option<DOMString>) { let blob = BlobData { - blob: value.clone(), + blob: value.unrooted(), name: filename.unwrap_or(~"default") }; self.data.insert(name.clone(), blob); } - pub fn Append_(&mut self, name: DOMString, value: DOMString) { + fn Append_(&mut self, name: DOMString, value: DOMString) { self.data.insert(name, StringData(value)); } } diff --git a/src/components/script/dom/htmlanchorelement.rs b/src/components/script/dom/htmlanchorelement.rs index c773e8b55b1..6b90e96053a 100644 --- a/src/components/script/dom/htmlanchorelement.rs +++ b/src/components/script/dom/htmlanchorelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLAnchorElementBinding; use dom::bindings::codegen::InheritTypes::HTMLAnchorElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAnchorElementTypeId; @@ -28,120 +28,149 @@ impl HTMLAnchorElementDerived for EventTarget { } impl HTMLAnchorElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAnchorElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLAnchorElement { HTMLAnchorElement { htmlelement: HTMLElement::new_inherited(HTMLAnchorElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAnchorElement> { - let element = HTMLAnchorElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLAnchorElement> { + let element = HTMLAnchorElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLAnchorElementBinding::Wrap) } } -impl HTMLAnchorElement { - pub fn Href(&self) -> DOMString { +pub trait HTMLAnchorElementMethods { + fn Href(&self) -> DOMString; + fn SetHref(&mut self, _href: DOMString) -> ErrorResult; + fn Target(&self) -> DOMString; + fn SetTarget(&self, _target: DOMString) -> ErrorResult; + fn Download(&self) -> DOMString; + fn SetDownload(&self, _download: DOMString) -> ErrorResult; + fn Ping(&self) -> DOMString; + fn SetPing(&self, _ping: DOMString) -> ErrorResult; + fn Rel(&self) -> DOMString; + fn SetRel(&self, _rel: DOMString) -> ErrorResult; + fn Hreflang(&self) -> DOMString; + fn SetHreflang(&self, _href_lang: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Text(&self) -> DOMString; + fn SetText(&mut self, _text: DOMString) -> ErrorResult; + fn Coords(&self) -> DOMString; + fn SetCoords(&mut self, _coords: DOMString) -> ErrorResult; + fn Charset(&self) -> DOMString; + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Rev(&self) -> DOMString; + fn SetRev(&mut self, _rev: DOMString) -> ErrorResult; + fn Shape(&self) -> DOMString; + fn SetShape(&mut self, _shape: DOMString) -> ErrorResult; +} + +impl<'a> HTMLAnchorElementMethods for JSRef<'a, HTMLAnchorElement> { + fn Href(&self) -> DOMString { ~"" } - pub fn SetHref(&mut self, _href: DOMString) -> ErrorResult { + fn SetHref(&mut self, _href: DOMString) -> ErrorResult { Ok(()) } - pub fn Target(&self) -> DOMString { + fn Target(&self) -> DOMString { ~"" } - pub fn SetTarget(&self, _target: DOMString) -> ErrorResult { + fn SetTarget(&self, _target: DOMString) -> ErrorResult { Ok(()) } - pub fn Download(&self) -> DOMString { + fn Download(&self) -> DOMString { ~"" } - pub fn SetDownload(&self, _download: DOMString) -> ErrorResult { + fn SetDownload(&self, _download: DOMString) -> ErrorResult { Ok(()) } - pub fn Ping(&self) -> DOMString { + fn Ping(&self) -> DOMString { ~"" } - pub fn SetPing(&self, _ping: DOMString) -> ErrorResult { + fn SetPing(&self, _ping: DOMString) -> ErrorResult { Ok(()) } - pub fn Rel(&self) -> DOMString { + fn Rel(&self) -> DOMString { ~"" } - pub fn SetRel(&self, _rel: DOMString) -> ErrorResult { + fn SetRel(&self, _rel: DOMString) -> ErrorResult { Ok(()) } - pub fn Hreflang(&self) -> DOMString { + fn Hreflang(&self) -> DOMString { ~"" } - pub fn SetHreflang(&self, _href_lang: DOMString) -> ErrorResult { + fn SetHreflang(&self, _href_lang: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Text(&self) -> DOMString { + fn Text(&self) -> DOMString { ~"" } - pub fn SetText(&mut self, _text: DOMString) -> ErrorResult { + fn SetText(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } - pub fn Coords(&self) -> DOMString { + fn Coords(&self) -> DOMString { ~"" } - pub fn SetCoords(&mut self, _coords: DOMString) -> ErrorResult { + fn SetCoords(&mut self, _coords: DOMString) -> ErrorResult { Ok(()) } - pub fn Charset(&self) -> DOMString { + fn Charset(&self) -> DOMString { ~"" } - pub fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Rev(&self) -> DOMString { + fn Rev(&self) -> DOMString { ~"" } - pub fn SetRev(&mut self, _rev: DOMString) -> ErrorResult { + fn SetRev(&mut self, _rev: DOMString) -> ErrorResult { Ok(()) } - pub fn Shape(&self) -> DOMString { + fn Shape(&self) -> DOMString { ~"" } - pub fn SetShape(&mut self, _shape: DOMString) -> ErrorResult { + fn SetShape(&mut self, _shape: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlappletelement.rs b/src/components/script/dom/htmlappletelement.rs index a6b4de0e21f..385750d0a16 100644 --- a/src/components/script/dom/htmlappletelement.rs +++ b/src/components/script/dom/htmlappletelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLAppletElementBinding; use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAppletElementTypeId; @@ -28,104 +28,129 @@ impl HTMLAppletElementDerived for EventTarget { } impl HTMLAppletElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAppletElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLAppletElement { HTMLAppletElement { htmlelement: HTMLElement::new_inherited(HTMLAppletElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAppletElement> { - let element = HTMLAppletElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLAppletElement> { + let element = HTMLAppletElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLAppletElementBinding::Wrap) } } -impl HTMLAppletElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLAppletElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Alt(&self) -> DOMString; + fn SetAlt(&self, _alt: DOMString) -> ErrorResult; + fn Archive(&self) -> DOMString; + fn SetArchive(&self, _archive: DOMString) -> ErrorResult; + fn Code(&self) -> DOMString; + fn SetCode(&self, _code: DOMString) -> ErrorResult; + fn CodeBase(&self) -> DOMString; + fn SetCodeBase(&self, _code_base: DOMString) -> ErrorResult; + fn Height(&self) -> DOMString; + fn SetHeight(&self, _height: DOMString) -> ErrorResult; + fn Hspace(&self) -> u32; + fn SetHspace(&mut self, _hspace: u32) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Object(&self) -> DOMString; + fn SetObject(&mut self, _object: DOMString) -> ErrorResult; + fn Vspace(&self) -> u32; + fn SetVspace(&mut self, _vspace: u32) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; +} + +impl<'a> HTMLAppletElementMethods for JSRef<'a, HTMLAppletElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Alt(&self) -> DOMString { + fn Alt(&self) -> DOMString { ~"" } - pub fn SetAlt(&self, _alt: DOMString) -> ErrorResult { + fn SetAlt(&self, _alt: DOMString) -> ErrorResult { Ok(()) } - pub fn Archive(&self) -> DOMString { + fn Archive(&self) -> DOMString { ~"" } - pub fn SetArchive(&self, _archive: DOMString) -> ErrorResult { + fn SetArchive(&self, _archive: DOMString) -> ErrorResult { Ok(()) } - pub fn Code(&self) -> DOMString { + fn Code(&self) -> DOMString { ~"" } - pub fn SetCode(&self, _code: DOMString) -> ErrorResult { + fn SetCode(&self, _code: DOMString) -> ErrorResult { Ok(()) } - pub fn CodeBase(&self) -> DOMString { + fn CodeBase(&self) -> DOMString { ~"" } - pub fn SetCodeBase(&self, _code_base: DOMString) -> ErrorResult { + fn SetCodeBase(&self, _code_base: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> DOMString { + fn Height(&self) -> DOMString { ~"" } - pub fn SetHeight(&self, _height: DOMString) -> ErrorResult { + fn SetHeight(&self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn Hspace(&self) -> u32 { + fn Hspace(&self) -> u32 { 0 } - pub fn SetHspace(&mut self, _hspace: u32) -> ErrorResult { + fn SetHspace(&mut self, _hspace: u32) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Object(&self) -> DOMString { + fn Object(&self) -> DOMString { ~"" } - pub fn SetObject(&mut self, _object: DOMString) -> ErrorResult { + fn SetObject(&mut self, _object: DOMString) -> ErrorResult { Ok(()) } - pub fn Vspace(&self) -> u32 { + fn Vspace(&self) -> u32 { 0 } - pub fn SetVspace(&mut self, _vspace: u32) -> ErrorResult { + fn SetVspace(&mut self, _vspace: u32) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlareaelement.rs b/src/components/script/dom/htmlareaelement.rs index e50ad671023..e09549b7a5e 100644 --- a/src/components/script/dom/htmlareaelement.rs +++ b/src/components/script/dom/htmlareaelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLAreaElementBinding; use dom::bindings::codegen::InheritTypes::HTMLAreaElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAreaElementTypeId; @@ -28,80 +28,99 @@ impl HTMLAreaElementDerived for EventTarget { } impl HTMLAreaElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAreaElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLAreaElement { HTMLAreaElement { htmlelement: HTMLElement::new_inherited(HTMLAreaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAreaElement> { - let element = HTMLAreaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLAreaElement> { + let element = HTMLAreaElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLAreaElementBinding::Wrap) } } -impl HTMLAreaElement { - pub fn Alt(&self) -> DOMString { +pub trait HTMLAreaElementMethods { + fn Alt(&self) -> DOMString; + fn SetAlt(&self, _alt: DOMString) -> ErrorResult; + fn Coords(&self) -> DOMString; + fn SetCoords(&self, _coords: DOMString) -> ErrorResult; + fn Shape(&self) -> DOMString; + fn SetShape(&self, _shape: DOMString) -> ErrorResult; + fn Href(&self) -> DOMString; + fn SetHref(&self, _href: DOMString) -> ErrorResult; + fn Target(&self) -> DOMString; + fn SetTarget(&self, _target: DOMString) -> ErrorResult; + fn Download(&self) -> DOMString; + fn SetDownload(&self, _download: DOMString) -> ErrorResult; + fn Ping(&self) -> DOMString; + fn SetPing(&self, _ping: DOMString) -> ErrorResult; + fn NoHref(&self) -> bool; + fn SetNoHref(&mut self, _no_href: bool) -> ErrorResult; +} + +impl<'a> HTMLAreaElementMethods for JSRef<'a, HTMLAreaElement> { + fn Alt(&self) -> DOMString { ~"" } - pub fn SetAlt(&self, _alt: DOMString) -> ErrorResult { + fn SetAlt(&self, _alt: DOMString) -> ErrorResult { Ok(()) } - pub fn Coords(&self) -> DOMString { + fn Coords(&self) -> DOMString { ~"" } - pub fn SetCoords(&self, _coords: DOMString) -> ErrorResult { + fn SetCoords(&self, _coords: DOMString) -> ErrorResult { Ok(()) } - pub fn Shape(&self) -> DOMString { + fn Shape(&self) -> DOMString { ~"" } - pub fn SetShape(&self, _shape: DOMString) -> ErrorResult { + fn SetShape(&self, _shape: DOMString) -> ErrorResult { Ok(()) } - pub fn Href(&self) -> DOMString { + fn Href(&self) -> DOMString { ~"" } - pub fn SetHref(&self, _href: DOMString) -> ErrorResult { + fn SetHref(&self, _href: DOMString) -> ErrorResult { Ok(()) } - pub fn Target(&self) -> DOMString { + fn Target(&self) -> DOMString { ~"" } - pub fn SetTarget(&self, _target: DOMString) -> ErrorResult { + fn SetTarget(&self, _target: DOMString) -> ErrorResult { Ok(()) } - pub fn Download(&self) -> DOMString { + fn Download(&self) -> DOMString { ~"" } - pub fn SetDownload(&self, _download: DOMString) -> ErrorResult { + fn SetDownload(&self, _download: DOMString) -> ErrorResult { Ok(()) } - pub fn Ping(&self) -> DOMString { + fn Ping(&self) -> DOMString { ~"" } - pub fn SetPing(&self, _ping: DOMString) -> ErrorResult { + fn SetPing(&self, _ping: DOMString) -> ErrorResult { Ok(()) } - pub fn NoHref(&self) -> bool { + fn NoHref(&self) -> bool { false } - pub fn SetNoHref(&mut self, _no_href: bool) -> ErrorResult { + fn SetNoHref(&mut self, _no_href: bool) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlaudioelement.rs b/src/components/script/dom/htmlaudioelement.rs index 20a36b60749..9cc697454d1 100644 --- a/src/components/script/dom/htmlaudioelement.rs +++ b/src/components/script/dom/htmlaudioelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLAudioElementBinding; use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLAudioElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLAudioElementDerived for EventTarget { } impl HTMLAudioElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAudioElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLAudioElement { HTMLAudioElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLAudioElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAudioElement> { - let element = HTMLAudioElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLAudioElement> { + let element = HTMLAudioElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLAudioElementBinding::Wrap) } } + +pub trait HTMLAudioElementMethods { +} diff --git a/src/components/script/dom/htmlbaseelement.rs b/src/components/script/dom/htmlbaseelement.rs index bedfd156284..1c75cd786bb 100644 --- a/src/components/script/dom/htmlbaseelement.rs +++ b/src/components/script/dom/htmlbaseelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLBaseElementBinding; use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived; use dom::bindings::error::ErrorResult; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLBaseElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -28,32 +28,39 @@ impl HTMLBaseElementDerived for EventTarget { } impl HTMLBaseElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBaseElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLBaseElement { HTMLBaseElement { htmlelement: HTMLElement::new_inherited(HTMLBaseElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBaseElement> { - let element = HTMLBaseElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLBaseElement> { + let element = HTMLBaseElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLBaseElementBinding::Wrap) } } -impl HTMLBaseElement { - pub fn Href(&self) -> DOMString { +pub trait HTMLBaseElementMethods { + fn Href(&self) -> DOMString; + fn SetHref(&self, _href: DOMString) -> ErrorResult; + fn Target(&self) -> DOMString; + fn SetTarget(&self, _target: DOMString) -> ErrorResult; +} + +impl<'a> HTMLBaseElementMethods for JSRef<'a, HTMLBaseElement> { + fn Href(&self) -> DOMString { ~"" } - pub fn SetHref(&self, _href: DOMString) -> ErrorResult { + fn SetHref(&self, _href: DOMString) -> ErrorResult { Ok(()) } - pub fn Target(&self) -> DOMString { + fn Target(&self) -> DOMString { ~"" } - pub fn SetTarget(&self, _target: DOMString) -> ErrorResult { + fn SetTarget(&self, _target: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlbodyelement.rs b/src/components/script/dom/htmlbodyelement.rs index 6e7e0349e40..4c28b446524 100644 --- a/src/components/script/dom/htmlbodyelement.rs +++ b/src/components/script/dom/htmlbodyelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLBodyElementBinding; use dom::bindings::codegen::InheritTypes::HTMLBodyElementDerived; use dom::bindings::error::ErrorResult; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLBodyElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -28,64 +28,79 @@ impl HTMLBodyElementDerived for EventTarget { } impl HTMLBodyElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBodyElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLBodyElement { HTMLBodyElement { htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBodyElement> { - let element = HTMLBodyElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLBodyElement> { + let element = HTMLBodyElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLBodyElementBinding::Wrap) } } -impl HTMLBodyElement { - pub fn Text(&self) -> DOMString { +pub trait HTMLBodyElementMethods { + fn Text(&self) -> DOMString; + fn SetText(&mut self, _text: DOMString) -> ErrorResult; + fn Link(&self) -> DOMString; + fn SetLink(&self, _link: DOMString) -> ErrorResult; + fn VLink(&self) -> DOMString; + fn SetVLink(&self, _v_link: DOMString) -> ErrorResult; + fn ALink(&self) -> DOMString; + fn SetALink(&self, _a_link: DOMString) -> ErrorResult; + fn BgColor(&self) -> DOMString; + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult; + fn Background(&self) -> DOMString; + fn SetBackground(&self, _background: DOMString) -> ErrorResult; +} + +impl<'a> HTMLBodyElementMethods for JSRef<'a, HTMLBodyElement> { + fn Text(&self) -> DOMString { ~"" } - pub fn SetText(&mut self, _text: DOMString) -> ErrorResult { + fn SetText(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } - pub fn Link(&self) -> DOMString { + fn Link(&self) -> DOMString { ~"" } - pub fn SetLink(&self, _link: DOMString) -> ErrorResult { + fn SetLink(&self, _link: DOMString) -> ErrorResult { Ok(()) } - pub fn VLink(&self) -> DOMString { + fn VLink(&self) -> DOMString { ~"" } - pub fn SetVLink(&self, _v_link: DOMString) -> ErrorResult { + fn SetVLink(&self, _v_link: DOMString) -> ErrorResult { Ok(()) } - pub fn ALink(&self) -> DOMString { + fn ALink(&self) -> DOMString { ~"" } - pub fn SetALink(&self, _a_link: DOMString) -> ErrorResult { + fn SetALink(&self, _a_link: DOMString) -> ErrorResult { Ok(()) } - pub fn BgColor(&self) -> DOMString { + fn BgColor(&self) -> DOMString { ~"" } - pub fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { Ok(()) } - pub fn Background(&self) -> DOMString { + fn Background(&self) -> DOMString { ~"" } - pub fn SetBackground(&self, _background: DOMString) -> ErrorResult { + fn SetBackground(&self, _background: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlbrelement.rs b/src/components/script/dom/htmlbrelement.rs index 1cf175468ae..bb1e57a2370 100644 --- a/src/components/script/dom/htmlbrelement.rs +++ b/src/components/script/dom/htmlbrelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLBRElementBinding; use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived; use dom::bindings::error::ErrorResult; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLBRElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -28,24 +28,29 @@ impl HTMLBRElementDerived for EventTarget { } impl HTMLBRElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBRElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLBRElement { HTMLBRElement { htmlelement: HTMLElement::new_inherited(HTMLBRElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBRElement> { - let element = HTMLBRElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLBRElement> { + let element = HTMLBRElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLBRElementBinding::Wrap) } } -impl HTMLBRElement { - pub fn Clear(&self) -> DOMString { +pub trait HTMLBRElementMethods { + fn Clear(&self) -> DOMString; + fn SetClear(&mut self, _text: DOMString) -> ErrorResult; +} + +impl<'a> HTMLBRElementMethods for JSRef<'a, HTMLBRElement> { + fn Clear(&self) -> DOMString { ~"" } - pub fn SetClear(&mut self, _text: DOMString) -> ErrorResult { + fn SetClear(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlbuttonelement.rs b/src/components/script/dom/htmlbuttonelement.rs index d40fdbe94be..782e9a0c0c8 100644 --- a/src/components/script/dom/htmlbuttonelement.rs +++ b/src/components/script/dom/htmlbuttonelement.rs @@ -4,14 +4,14 @@ use dom::bindings::codegen::BindingDeclarations::HTMLButtonElementBinding; use dom::bindings::codegen::InheritTypes::HTMLButtonElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLButtonElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::HTMLFormElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; use dom::validitystate::ValidityState; use servo_util::str::DOMString; @@ -30,131 +30,158 @@ impl HTMLButtonElementDerived for EventTarget { } impl HTMLButtonElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLButtonElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLButtonElement { HTMLButtonElement { htmlelement: HTMLElement::new_inherited(HTMLButtonElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLButtonElement> { - let element = HTMLButtonElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLButtonElement> { + let element = HTMLButtonElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLButtonElementBinding::Wrap) } } -impl HTMLButtonElement { - pub fn Autofocus(&self) -> bool { +pub trait HTMLButtonElementMethods { + fn Autofocus(&self) -> bool; + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult; + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn FormAction(&self) -> DOMString; + fn SetFormAction(&mut self, _formaction: DOMString) -> ErrorResult; + fn FormEnctype(&self) -> DOMString; + fn SetFormEnctype(&mut self, _formenctype: DOMString) -> ErrorResult; + fn FormMethod(&self) -> DOMString; + fn SetFormMethod(&mut self, _formmethod: DOMString) -> ErrorResult; + fn FormNoValidate(&self) -> bool; + fn SetFormNoValidate(&mut self, _novalidate: bool) -> ErrorResult; + fn FormTarget(&self) -> DOMString; + fn SetFormTarget(&mut self, _formtarget: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; + fn WillValidate(&self) -> bool; + fn SetWillValidate(&mut self, _will_validate: bool); + fn Validity(&self) -> Temporary<ValidityState>; + fn ValidationMessage(&self) -> DOMString; + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&mut self, _error: DOMString); +} + +impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { + fn Autofocus(&self) -> bool { false } - pub fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { Ok(()) } - pub fn Disabled(&self) -> bool { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn FormAction(&self) -> DOMString { + fn FormAction(&self) -> DOMString { ~"" } - pub fn SetFormAction(&mut self, _formaction: DOMString) -> ErrorResult { + fn SetFormAction(&mut self, _formaction: DOMString) -> ErrorResult { Ok(()) } - pub fn FormEnctype(&self) -> DOMString { + fn FormEnctype(&self) -> DOMString { ~"" } - pub fn SetFormEnctype(&mut self, _formenctype: DOMString) -> ErrorResult { + fn SetFormEnctype(&mut self, _formenctype: DOMString) -> ErrorResult { Ok(()) } - pub fn FormMethod(&self) -> DOMString { + fn FormMethod(&self) -> DOMString { ~"" } - pub fn SetFormMethod(&mut self, _formmethod: DOMString) -> ErrorResult { + fn SetFormMethod(&mut self, _formmethod: DOMString) -> ErrorResult { Ok(()) } - pub fn FormNoValidate(&self) -> bool { + fn FormNoValidate(&self) -> bool { false } - pub fn SetFormNoValidate(&mut self, _novalidate: bool) -> ErrorResult { + fn SetFormNoValidate(&mut self, _novalidate: bool) -> ErrorResult { Ok(()) } - pub fn FormTarget(&self) -> DOMString { + fn FormTarget(&self) -> DOMString { ~"" } - pub fn SetFormTarget(&mut self, _formtarget: DOMString) -> ErrorResult { + fn SetFormTarget(&mut self, _formtarget: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn SetWillValidate(&mut self, _will_validate: bool) { - } - - pub fn Validity(&self) -> JS<ValidityState> { - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - ValidityState::new(&doc.window) + fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { + fn Validity(&self) -> Temporary<ValidityState> { + let window = window_from_node(self).root(); + ValidityState::new(&*window) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { Ok(()) } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { true } - pub fn SetCustomValidity(&mut self, _error: DOMString) { + fn SetCustomValidity(&mut self, _error: DOMString) { } } diff --git a/src/components/script/dom/htmlcanvaselement.rs b/src/components/script/dom/htmlcanvaselement.rs index 6bf26adc593..5970af52eb3 100644 --- a/src/components/script/dom/htmlcanvaselement.rs +++ b/src/components/script/dom/htmlcanvaselement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLCanvasElementBinding; use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::{ErrorResult}; use dom::document::Document; use dom::element::HTMLCanvasElementTypeId; @@ -28,32 +28,39 @@ impl HTMLCanvasElementDerived for EventTarget { } impl HTMLCanvasElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLCanvasElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLCanvasElement { HTMLCanvasElement { htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLCanvasElement> { - let element = HTMLCanvasElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLCanvasElement> { + let element = HTMLCanvasElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLCanvasElementBinding::Wrap) } } -impl HTMLCanvasElement { - pub fn Width(&self) -> u32 { +pub trait HTMLCanvasElementMethods { + fn Width(&self) -> u32; + fn SetWidth(&mut self, _width: u32) -> ErrorResult; + fn Height(&self) -> u32; + fn SetHeight(&mut self, _height: u32) -> ErrorResult; +} + +impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { + fn Width(&self) -> u32 { 0 } - pub fn SetWidth(&mut self, _width: u32) -> ErrorResult { + fn SetWidth(&mut self, _width: u32) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> u32 { + fn Height(&self) -> u32 { 0 } - pub fn SetHeight(&mut self, _height: u32) -> ErrorResult { + fn SetHeight(&mut self, _height: u32) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 79b35487634..82b0d54693f 100644 --- a/src/components/script/dom/htmlcollection.rs +++ b/src/components/script/dom/htmlcollection.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast}; use dom::bindings::codegen::BindingDeclarations::HTMLCollectionBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; use dom::node::{Node, NodeHelpers}; @@ -15,7 +15,7 @@ use servo_util::str::{DOMString, split_html_space_chars}; use serialize::{Encoder, Encodable}; pub trait CollectionFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool; + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool; } impl<S: Encoder<E>, E> Encodable<S, E> for ~CollectionFilter { @@ -38,33 +38,33 @@ pub struct HTMLCollection { } impl HTMLCollection { - pub fn new_inherited(window: JS<Window>, collection: CollectionTypeId) -> HTMLCollection { + pub fn new_inherited(window: &JSRef<Window>, collection: CollectionTypeId) -> HTMLCollection { HTMLCollection { collection: collection, reflector_: Reflector::new(), - window: window, + window: window.unrooted(), } } - pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> { - reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection), + pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> Temporary<HTMLCollection> { + reflect_dom_object(~HTMLCollection::new_inherited(window, collection), window, HTMLCollectionBinding::Wrap) } } impl HTMLCollection { - pub fn create(window: &JS<Window>, root: &JS<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> { - HTMLCollection::new(window, Live(root.clone(), filter)) + pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> Temporary<HTMLCollection> { + HTMLCollection::new(window, Live(root.unrooted(), filter)) } - pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag: DOMString) - -> JS<HTMLCollection> { + pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString) + -> Temporary<HTMLCollection> { struct TagNameFilter { tag: DOMString } impl CollectionFilter for TagNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == self.tag + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == self.tag } } let filter = TagNameFilter { @@ -73,15 +73,15 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag: DOMString, - namespace: Namespace) -> JS<HTMLCollection> { + pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString, + namespace: Namespace) -> Temporary<HTMLCollection> { struct TagNameNSFilter { tag: DOMString, namespace: Namespace } impl CollectionFilter for TagNameNSFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().namespace == self.namespace && elem.get().local_name == self.tag + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().namespace == self.namespace && elem.deref().local_name == self.tag } } let filter = TagNameNSFilter { @@ -91,13 +91,13 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) - -> JS<HTMLCollection> { + pub fn by_class_name(window: &JSRef<Window>, root: &JSRef<Node>, classes: DOMString) + -> Temporary<HTMLCollection> { struct ClassNameFilter { classes: Vec<DOMString> } impl CollectionFilter for ClassNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { self.classes.iter().all(|class| elem.has_class(*class)) } } @@ -107,46 +107,65 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn children(window: &JS<Window>, root: &JS<Node>) -> JS<HTMLCollection> { + pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> Temporary<HTMLCollection> { struct ElementChildFilter; impl CollectionFilter for ElementChildFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool { - root.is_parent_of(&NodeCast::from(elem)) + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool { + root.is_parent_of(NodeCast::from_ref(elem)) } } HTMLCollection::create(window, root, ~ElementChildFilter) } } -impl HTMLCollection { +pub trait HTMLCollectionMethods { + fn Length(&self) -> u32; + fn Item(&self, index: u32) -> Option<Temporary<Element>>; + fn NamedItem(&self, key: DOMString) -> Option<Temporary<Element>>; + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Element>>; + fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Temporary<Element>>; +} + +impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { // http://dom.spec.whatwg.org/#dom-htmlcollection-length - pub fn Length(&self) -> u32 { + fn Length(&self) -> u32 { match self.collection { Static(ref elems) => elems.len() as u32, - Live(ref root, ref filter) => root.traverse_preorder() - .count(|child| { - let elem: Option<JS<Element>> = ElementCast::to(&child); - elem.map_or(false, |elem| filter.filter(&elem, root)) - }) as u32 + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .count(|child| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&child); + elem.map_or(false, |elem| filter.filter(elem, &*root)) + }) as u32 + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-item - pub fn Item(&self, index: u32) -> Option<JS<Element>> { + fn Item(&self, index: u32) -> Option<Temporary<Element>> { match self.collection { Static(ref elems) => elems .as_slice() .get(index as uint) - .map(|elem| elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .nth(index as uint).clone() + .map(|elem| Temporary::new(elem.clone())), + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .map(|elem| elem.clone()) + }) + .nth(index as uint) + .clone() + .map(|elem| Temporary::from_rooted(&elem)) + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem - pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> { + fn NamedItem(&self, key: DOMString) -> Option<Temporary<Element>> { // Step 1. if key.is_empty() { return None; @@ -155,29 +174,34 @@ impl HTMLCollection { // Step 2. match self.collection { Static(ref elems) => elems.iter() + .map(|elem| elem.root()) .find(|elem| { elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .find(|elem| { - elem.get_string_attribute("name") == key || - elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_elem.clone()) + .map(|maybe_elem| Temporary::from_rooted(&*maybe_elem)), + Live(ref root, ref filter) => { + let root = root.root(); + root.deref().traverse_preorder() + .filter_map(|node| { + let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node); + elem.filtered(|&elem| filter.filter(elem, &*root)) + .map(|elem| elem.clone()) + }) + .find(|elem| { + elem.get_string_attribute("name") == key || + elem.get_string_attribute("id") == key }) + .map(|maybe_elem| Temporary::from_rooted(&maybe_elem)) + } } } -} -impl HTMLCollection { - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> { + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Element>> { let maybe_elem = self.Item(index); *found = maybe_elem.is_some(); maybe_elem } - pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> { + fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Temporary<Element>> { match maybe_name { Some(name) => { let maybe_elem = self.NamedItem(name); diff --git a/src/components/script/dom/htmldataelement.rs b/src/components/script/dom/htmldataelement.rs index e242be54d9d..26090be7632 100644 --- a/src/components/script/dom/htmldataelement.rs +++ b/src/components/script/dom/htmldataelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLDataElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDataElementTypeId; @@ -28,24 +28,29 @@ impl HTMLDataElementDerived for EventTarget { } impl HTMLDataElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLDataElement { HTMLDataElement { htmlelement: HTMLElement::new_inherited(HTMLDataElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataElement> { - let element = HTMLDataElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLDataElement> { + let element = HTMLDataElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLDataElementBinding::Wrap) } } -impl HTMLDataElement { - pub fn Value(&self) -> DOMString { +pub trait HTMLDataElementMethods { + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; +} + +impl<'a> HTMLDataElementMethods for JSRef<'a, HTMLDataElement> { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmldatalistelement.rs b/src/components/script/dom/htmldatalistelement.rs index 7a5d5329b18..1bcdd936cdc 100644 --- a/src/components/script/dom/htmldatalistelement.rs +++ b/src/components/script/dom/htmldatalistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLDataListElementBinding; use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::{Element, HTMLDataListElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -28,28 +28,33 @@ impl HTMLDataListElementDerived for EventTarget { } impl HTMLDataListElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataListElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLDataListElement { HTMLDataListElement { htmlelement: HTMLElement::new_inherited(HTMLDataListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataListElement> { - let element = HTMLDataListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLDataListElement> { + let element = HTMLDataListElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLDataListElementBinding::Wrap) } } -impl HTMLDataListElement { - pub fn Options(&self, abstract_self: &JS<HTMLDataListElement>) -> JS<HTMLCollection> { +pub trait HTMLDataListElementMethods { + fn Options(&self) -> Temporary<HTMLCollection>; +} + +impl<'a> HTMLDataListElementMethods for JSRef<'a, HTMLDataListElement> { + fn Options(&self) -> Temporary<HTMLCollection> { struct HTMLDataListOptionsFilter; impl CollectionFilter for HTMLDataListOptionsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"option" + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.deref().local_name == ~"option" } } - let node: JS<Node> = NodeCast::from(abstract_self); + let node: &JSRef<Node> = NodeCast::from_ref(self); let filter = ~HTMLDataListOptionsFilter; - HTMLCollection::create(&window_from_node(&node), &node, filter) + let window = window_from_node(node).root(); + HTMLCollection::create(&*window, node, filter) } } diff --git a/src/components/script/dom/htmldirectoryelement.rs b/src/components/script/dom/htmldirectoryelement.rs index d356fb0bb51..c16d0f01f34 100644 --- a/src/components/script/dom/htmldirectoryelement.rs +++ b/src/components/script/dom/htmldirectoryelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLDirectoryElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDirectoryElementTypeId; @@ -28,24 +28,29 @@ impl HTMLDirectoryElementDerived for EventTarget { } impl HTMLDirectoryElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDirectoryElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLDirectoryElement { HTMLDirectoryElement { htmlelement: HTMLElement::new_inherited(HTMLDirectoryElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDirectoryElement> { - let element = HTMLDirectoryElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLDirectoryElement> { + let element = HTMLDirectoryElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLDirectoryElementBinding::Wrap) } } -impl HTMLDirectoryElement { - pub fn Compact(&self) -> bool { +pub trait HTMLDirectoryElementMethods { + fn Compact(&self) -> bool; + fn SetCompact(&mut self, _compact: bool) -> ErrorResult; +} + +impl<'a> HTMLDirectoryElementMethods for JSRef<'a, HTMLDirectoryElement> { + fn Compact(&self) -> bool { false } - pub fn SetCompact(&mut self, _compact: bool) -> ErrorResult { + fn SetCompact(&mut self, _compact: bool) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmldivelement.rs b/src/components/script/dom/htmldivelement.rs index e018a1a0c3c..5f49ce250ed 100644 --- a/src/components/script/dom/htmldivelement.rs +++ b/src/components/script/dom/htmldivelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLDivElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDivElementTypeId; @@ -28,24 +28,29 @@ impl HTMLDivElementDerived for EventTarget { } impl HTMLDivElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDivElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLDivElement { HTMLDivElement { htmlelement: HTMLElement::new_inherited(HTMLDivElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDivElement> { - let element = HTMLDivElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLDivElement> { + let element = HTMLDivElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLDivElementBinding::Wrap) } } -impl HTMLDivElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLDivElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLDivElementMethods for JSRef<'a, HTMLDivElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmldlistelement.rs b/src/components/script/dom/htmldlistelement.rs index f2f9784764e..db57d180049 100644 --- a/src/components/script/dom/htmldlistelement.rs +++ b/src/components/script/dom/htmldlistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLDListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDListElementTypeId; @@ -28,32 +28,40 @@ impl HTMLDListElementDerived for EventTarget { } impl HTMLDListElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDListElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLDListElement { HTMLDListElement { htmlelement: HTMLElement::new_inherited(HTMLDListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDListElement> { - let element = HTMLDListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLDListElement> { + let element = HTMLDListElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLDListElementBinding::Wrap) } } -impl HTMLDListElement { - pub fn Compact(&self) -> bool { +pub trait HTMLDListElementMethods { + fn Compact(&self) -> bool; + fn SetCompact(&mut self, _compact: bool) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; +} + +impl<'a> HTMLDListElementMethods for JSRef<'a, HTMLDListElement> { + fn Compact(&self) -> bool { false } - pub fn SetCompact(&mut self, _compact: bool) -> ErrorResult { + fn SetCompact(&mut self, _compact: bool) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } } + diff --git a/src/components/script/dom/htmlelement.rs b/src/components/script/dom/htmlelement.rs index 61ebf7d1301..3443e62e51f 100644 --- a/src/components/script/dom/htmlelement.rs +++ b/src/components/script/dom/htmlelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLElementBinding; use dom::bindings::codegen::InheritTypes::ElementCast; use dom::bindings::codegen::InheritTypes::HTMLElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::{Element, ElementTypeId, HTMLElementTypeId}; @@ -33,140 +33,173 @@ impl HTMLElementDerived for EventTarget { } impl HTMLElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: &JSRef<Document>) -> HTMLElement { HTMLElement { element: Element::new_inherited(type_id, tag_name, namespace::HTML, None, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLElement> { - let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLElement> { + let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document); Node::reflect_node(~element, document, HTMLElementBinding::Wrap) } } -impl HTMLElement { - pub fn Title(&self) -> DOMString { +pub trait HTMLElementMethods { + fn Title(&self) -> DOMString; + fn SetTitle(&mut self, _title: DOMString); + fn Lang(&self) -> DOMString; + fn SetLang(&mut self, _lang: DOMString); + fn Dir(&self) -> DOMString; + fn SetDir(&mut self, _dir: DOMString) -> ErrorResult; + fn GetItemValue(&self, _cx: *JSContext) -> Fallible<JSVal>; + fn SetItemValue(&mut self, _cx: *JSContext, _val: JSVal) -> ErrorResult; + fn Hidden(&self) -> bool; + fn SetHidden(&mut self, _hidden: bool) -> ErrorResult; + fn Click(&self); + fn TabIndex(&self) -> i32; + fn SetTabIndex(&mut self, _index: i32) -> ErrorResult; + fn Focus(&self) -> ErrorResult; + fn Blur(&self) -> ErrorResult; + fn AccessKey(&self) -> DOMString; + fn SetAccessKey(&self, _key: DOMString) -> ErrorResult; + fn AccessKeyLabel(&self) -> DOMString; + fn Draggable(&self) -> bool; + fn SetDraggable(&mut self, _draggable: bool) -> ErrorResult; + fn ContentEditable(&self) -> DOMString; + fn SetContentEditable(&mut self, _val: DOMString) -> ErrorResult; + fn IsContentEditable(&self) -> bool; + fn Spellcheck(&self) -> bool; + fn SetSpellcheck(&self, _val: bool) -> ErrorResult; + fn GetOffsetParent(&self) -> Option<Temporary<Element>>; + fn OffsetTop(&self) -> i32; + fn OffsetLeft(&self) -> i32; + fn OffsetWidth(&self) -> i32; + fn OffsetHeight(&self) -> i32; +} + +impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { + fn Title(&self) -> DOMString { ~"" } - pub fn SetTitle(&mut self, _title: DOMString) { + fn SetTitle(&mut self, _title: DOMString) { } - pub fn Lang(&self) -> DOMString { + fn Lang(&self) -> DOMString { ~"" } - pub fn SetLang(&mut self, _lang: DOMString) { + fn SetLang(&mut self, _lang: DOMString) { } - pub fn Dir(&self) -> DOMString { + fn Dir(&self) -> DOMString { ~"" } - pub fn SetDir(&mut self, _dir: DOMString) -> ErrorResult { + fn SetDir(&mut self, _dir: DOMString) -> ErrorResult { Ok(()) } - pub fn GetItemValue(&self, _cx: *JSContext) -> Fallible<JSVal> { + fn GetItemValue(&self, _cx: *JSContext) -> Fallible<JSVal> { Ok(NullValue()) } - pub fn SetItemValue(&mut self, _cx: *JSContext, _val: JSVal) -> ErrorResult { + fn SetItemValue(&mut self, _cx: *JSContext, _val: JSVal) -> ErrorResult { Ok(()) } - pub fn Hidden(&self) -> bool { + fn Hidden(&self) -> bool { false } - pub fn SetHidden(&mut self, _hidden: bool) -> ErrorResult { + fn SetHidden(&mut self, _hidden: bool) -> ErrorResult { Ok(()) } - pub fn Click(&self) { + fn Click(&self) { } - pub fn TabIndex(&self) -> i32 { + fn TabIndex(&self) -> i32 { 0 } - pub fn SetTabIndex(&mut self, _index: i32) -> ErrorResult { + fn SetTabIndex(&mut self, _index: i32) -> ErrorResult { Ok(()) } - pub fn Focus(&self) -> ErrorResult { + fn Focus(&self) -> ErrorResult { Ok(()) } - pub fn Blur(&self) -> ErrorResult { + fn Blur(&self) -> ErrorResult { Ok(()) } - pub fn AccessKey(&self) -> DOMString { + fn AccessKey(&self) -> DOMString { ~"" } - pub fn SetAccessKey(&self, _key: DOMString) -> ErrorResult { + fn SetAccessKey(&self, _key: DOMString) -> ErrorResult { Ok(()) } - pub fn AccessKeyLabel(&self) -> DOMString { + fn AccessKeyLabel(&self) -> DOMString { ~"" } - pub fn Draggable(&self) -> bool { + fn Draggable(&self) -> bool { false } - pub fn SetDraggable(&mut self, _draggable: bool) -> ErrorResult { + fn SetDraggable(&mut self, _draggable: bool) -> ErrorResult { Ok(()) } - pub fn ContentEditable(&self) -> DOMString { + fn ContentEditable(&self) -> DOMString { ~"" } - pub fn SetContentEditable(&mut self, _val: DOMString) -> ErrorResult { + fn SetContentEditable(&mut self, _val: DOMString) -> ErrorResult { Ok(()) } - pub fn IsContentEditable(&self) -> bool { + fn IsContentEditable(&self) -> bool { false } - pub fn Spellcheck(&self) -> bool { + fn Spellcheck(&self) -> bool { false } - pub fn SetSpellcheck(&self, _val: bool) -> ErrorResult { + fn SetSpellcheck(&self, _val: bool) -> ErrorResult { Ok(()) } - pub fn GetOffsetParent(&self) -> Option<JS<Element>> { + fn GetOffsetParent(&self) -> Option<Temporary<Element>> { None } - pub fn OffsetTop(&self) -> i32 { + fn OffsetTop(&self) -> i32 { 0 } - pub fn OffsetLeft(&self) -> i32 { + fn OffsetLeft(&self) -> i32 { 0 } - pub fn OffsetWidth(&self) -> i32 { + fn OffsetWidth(&self) -> i32 { 0 } - pub fn OffsetHeight(&self) -> i32 { + fn OffsetHeight(&self) -> i32 { 0 } } -impl VirtualMethods for JS<HTMLElement> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let element: JS<Element> = ElementCast::from(self); - Some(~element as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); + Some(element as &mut VirtualMethods:) } } diff --git a/src/components/script/dom/htmlembedelement.rs b/src/components/script/dom/htmlembedelement.rs index d0a2e436043..b1b1134f0ac 100644 --- a/src/components/script/dom/htmlembedelement.rs +++ b/src/components/script/dom/htmlembedelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLEmbedElementBinding; use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLEmbedElementTypeId; @@ -28,68 +28,84 @@ impl HTMLEmbedElementDerived for EventTarget { } impl HTMLEmbedElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLEmbedElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLEmbedElement { HTMLEmbedElement { htmlelement: HTMLElement::new_inherited(HTMLEmbedElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLEmbedElement> { - let element = HTMLEmbedElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLEmbedElement> { + let element = HTMLEmbedElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLEmbedElementBinding::Wrap) } } -impl HTMLEmbedElement { - pub fn Src(&self) -> DOMString { +pub trait HTMLEmbedElementMethods { + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; + fn Height(&self) -> DOMString; + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _type: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _type: DOMString) -> ErrorResult; + fn GetSVGDocument(&self) -> Option<Temporary<Document>>; +} + +impl<'a> HTMLEmbedElementMethods for JSRef<'a, HTMLEmbedElement> { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> DOMString { + fn Height(&self) -> DOMString { ~"" } - pub fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _type: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _type: DOMString) -> ErrorResult { + fn SetName(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<JS<Document>> { + fn GetSVGDocument(&self) -> Option<Temporary<Document>> { None } } diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs index 21116ee41fb..73207cda9a9 100644 --- a/src/components/script/dom/htmlfieldsetelement.rs +++ b/src/components/script/dom/htmlfieldsetelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLFieldSetElementBinding; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFieldSetElementDerived, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLFieldSetElementTypeId}; @@ -31,77 +31,92 @@ impl HTMLFieldSetElementDerived for EventTarget { } impl HTMLFieldSetElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFieldSetElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFieldSetElement { HTMLFieldSetElement { htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFieldSetElement> { - let element = HTMLFieldSetElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFieldSetElement> { + let element = HTMLFieldSetElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLFieldSetElementBinding::Wrap) } } -impl HTMLFieldSetElement { - pub fn Disabled(&self) -> bool { +pub trait HTMLFieldSetElementMethods { + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn Elements(&self) -> Temporary<HTMLCollection>; + fn WillValidate(&self) -> bool; + fn Validity(&self) -> Temporary<ValidityState>; + fn ValidationMessage(&self) -> DOMString; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&mut self, _error: DOMString); +} + +impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } // http://www.whatwg.org/html/#dom-fieldset-elements - pub fn Elements(&self, abstract_self: &JS<HTMLFieldSetElement>) -> JS<HTMLCollection> { + fn Elements(&self) -> Temporary<HTMLCollection> { struct ElementsFilter; impl CollectionFilter for ElementsFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool { static tag_names: StaticStringVec = &["button", "fieldset", "input", "keygen", "object", "output", "select", "textarea"]; - let root: &JS<Element> = &ElementCast::to(root).unwrap(); - elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.get().local_name) + let root: &JSRef<Element> = ElementCast::to_ref(root).unwrap(); + elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.deref().local_name) } } - let node: JS<Node> = NodeCast::from(abstract_self); + let node: &JSRef<Node> = NodeCast::from_ref(self); let filter = ~ElementsFilter; - HTMLCollection::create(&window_from_node(&node), &node, filter) + let window = window_from_node(node).root(); + HTMLCollection::create(&*window, node, filter) } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn Validity(&self) -> JS<ValidityState> { - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - ValidityState::new(&doc.window) + fn Validity(&self) -> Temporary<ValidityState> { + let window = window_from_node(self).root(); + ValidityState::new(&*window) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { false } - pub fn SetCustomValidity(&mut self, _error: DOMString) { + fn SetCustomValidity(&mut self, _error: DOMString) { } } diff --git a/src/components/script/dom/htmlfontelement.rs b/src/components/script/dom/htmlfontelement.rs index 6eae087cdcd..e561385da49 100644 --- a/src/components/script/dom/htmlfontelement.rs +++ b/src/components/script/dom/htmlfontelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLFontElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFontElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFontElementTypeId; @@ -28,40 +28,49 @@ impl HTMLFontElementDerived for EventTarget { } impl HTMLFontElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFontElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFontElement { HTMLFontElement { htmlelement: HTMLElement::new_inherited(HTMLFontElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFontElement> { - let element = HTMLFontElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFontElement> { + let element = HTMLFontElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLFontElementBinding::Wrap) } } -impl HTMLFontElement { - pub fn Color(&self) -> DOMString { +pub trait HTMLFontElementMethods { + fn Color(&self) -> DOMString; + fn SetColor(&mut self, _color: DOMString) -> ErrorResult; + fn Face(&self) -> DOMString; + fn SetFace(&mut self, _face: DOMString) -> ErrorResult; + fn Size(&self) -> DOMString; + fn SetSize(&mut self, _size: DOMString) -> ErrorResult; +} + +impl<'a> HTMLFontElementMethods for JSRef<'a, HTMLFontElement> { + fn Color(&self) -> DOMString { ~"" } - pub fn SetColor(&mut self, _color: DOMString) -> ErrorResult { + fn SetColor(&mut self, _color: DOMString) -> ErrorResult { Ok(()) } - pub fn Face(&self) -> DOMString { + fn Face(&self) -> DOMString { ~"" } - pub fn SetFace(&mut self, _face: DOMString) -> ErrorResult { + fn SetFace(&mut self, _face: DOMString) -> ErrorResult { Ok(()) } - pub fn Size(&self) -> DOMString { + fn Size(&self) -> DOMString { ~"" } - pub fn SetSize(&mut self, _size: DOMString) -> ErrorResult { + fn SetSize(&mut self, _size: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlformelement.rs b/src/components/script/dom/htmlformelement.rs index 3fdf2a4ba7f..445ad6e0831 100644 --- a/src/components/script/dom/htmlformelement.rs +++ b/src/components/script/dom/htmlformelement.rs @@ -4,14 +4,14 @@ use dom::bindings::codegen::BindingDeclarations::HTMLFormElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLFormElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::{HTMLCollection, Static}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; use servo_util::str::DOMString; #[deriving(Encodable)] @@ -29,114 +29,140 @@ impl HTMLFormElementDerived for EventTarget { } impl HTMLFormElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFormElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFormElement { HTMLFormElement { htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFormElement> { - let element = HTMLFormElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFormElement> { + let element = HTMLFormElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLFormElementBinding::Wrap) } } -impl HTMLFormElement { - pub fn AcceptCharset(&self) -> DOMString { +pub trait HTMLFormElementMethods { + fn AcceptCharset(&self) -> DOMString; + fn SetAcceptCharset(&mut self, _accept_charset: DOMString) -> ErrorResult; + fn Action(&self) -> DOMString; + fn SetAction(&mut self, _action: DOMString) -> ErrorResult; + fn Autocomplete(&self) -> DOMString; + fn SetAutocomplete(&mut self, _autocomplete: DOMString) -> ErrorResult; + fn Enctype(&self) -> DOMString; + fn SetEnctype(&mut self, _enctype: DOMString) -> ErrorResult; + fn Encoding(&self) -> DOMString; + fn SetEncoding(&mut self, _encoding: DOMString) -> ErrorResult; + fn Method(&self) -> DOMString; + fn SetMethod(&mut self, _method: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn NoValidate(&self) -> bool; + fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult; + fn Target(&self) -> DOMString; + fn SetTarget(&mut self, _target: DOMString) -> ErrorResult; + fn Elements(&self) -> Temporary<HTMLCollection>; + fn Length(&self) -> i32; + fn Submit(&self) -> ErrorResult; + fn Reset(&self); + fn CheckValidity(&self) -> bool; + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element>; +} + +impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> { + fn AcceptCharset(&self) -> DOMString { ~"" } - pub fn SetAcceptCharset(&mut self, _accept_charset: DOMString) -> ErrorResult { + fn SetAcceptCharset(&mut self, _accept_charset: DOMString) -> ErrorResult { Ok(()) } - pub fn Action(&self) -> DOMString { + fn Action(&self) -> DOMString { ~"" } - pub fn SetAction(&mut self, _action: DOMString) -> ErrorResult { + fn SetAction(&mut self, _action: DOMString) -> ErrorResult { Ok(()) } - pub fn Autocomplete(&self) -> DOMString { + fn Autocomplete(&self) -> DOMString { ~"" } - pub fn SetAutocomplete(&mut self, _autocomplete: DOMString) -> ErrorResult { + fn SetAutocomplete(&mut self, _autocomplete: DOMString) -> ErrorResult { Ok(()) } - pub fn Enctype(&self) -> DOMString { + fn Enctype(&self) -> DOMString { ~"" } - pub fn SetEnctype(&mut self, _enctype: DOMString) -> ErrorResult { + fn SetEnctype(&mut self, _enctype: DOMString) -> ErrorResult { Ok(()) } - pub fn Encoding(&self) -> DOMString { + fn Encoding(&self) -> DOMString { ~"" } - pub fn SetEncoding(&mut self, _encoding: DOMString) -> ErrorResult { + fn SetEncoding(&mut self, _encoding: DOMString) -> ErrorResult { Ok(()) } - pub fn Method(&self) -> DOMString { + fn Method(&self) -> DOMString { ~"" } - pub fn SetMethod(&mut self, _method: DOMString) -> ErrorResult { + fn SetMethod(&mut self, _method: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn NoValidate(&self) -> bool { + fn NoValidate(&self) -> bool { false } - pub fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult { + fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult { Ok(()) } - pub fn Target(&self) -> DOMString { + fn Target(&self) -> DOMString { ~"" } - pub fn SetTarget(&mut self, _target: DOMString) -> ErrorResult { + fn SetTarget(&mut self, _target: DOMString) -> ErrorResult { Ok(()) } - pub fn Elements(&self) -> JS<HTMLCollection> { + fn Elements(&self) -> Temporary<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1844 - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::new(&doc.window, Static(vec!())) + let window = window_from_node(self).root(); + HTMLCollection::new(&*window, Static(vec!())) } - pub fn Length(&self) -> i32 { + fn Length(&self) -> i32 { 0 } - pub fn Submit(&self) -> ErrorResult { + fn Submit(&self) -> ErrorResult { Ok(()) } - pub fn Reset(&self) { + fn Reset(&self) { } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { false } - pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> JS<Element> { + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element> { fail!("Not implemented.") } } diff --git a/src/components/script/dom/htmlframeelement.rs b/src/components/script/dom/htmlframeelement.rs index a0ac8293ff7..858a182ba10 100644 --- a/src/components/script/dom/htmlframeelement.rs +++ b/src/components/script/dom/htmlframeelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLFrameElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFrameElementTypeId; @@ -29,88 +29,109 @@ impl HTMLFrameElementDerived for EventTarget { } impl HTMLFrameElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFrameElement { HTMLFrameElement { htmlelement: HTMLElement::new_inherited(HTMLFrameElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameElement> { - let element = HTMLFrameElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFrameElement> { + let element = HTMLFrameElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLFrameElementBinding::Wrap) } } -impl HTMLFrameElement { - pub fn Name(&self) -> DOMString { +pub trait HTMLFrameElementMethods { + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Scrolling(&self) -> DOMString; + fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult; + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn FrameBorder(&self) -> DOMString; + fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult; + fn LongDesc(&self) -> DOMString; + fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult; + fn NoResize(&self) -> bool; + fn SetNoResize(&mut self, _no_resize: bool) -> ErrorResult; + fn GetContentDocument(&self) -> Option<Temporary<Document>>; + fn GetContentWindow(&self) -> Option<Temporary<Window>>; + fn MarginHeight(&self) -> DOMString; + fn SetMarginHeight(&mut self, _height: DOMString) -> ErrorResult; + fn MarginWidth(&self) -> DOMString; + fn SetMarginWidth(&mut self, _height: DOMString) -> ErrorResult; +} + +impl<'a> HTMLFrameElementMethods for JSRef<'a, HTMLFrameElement> { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Scrolling(&self) -> DOMString { + fn Scrolling(&self) -> DOMString { ~"" } - pub fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult { + fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult { Ok(()) } - pub fn Src(&self) -> DOMString { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn FrameBorder(&self) -> DOMString { + fn FrameBorder(&self) -> DOMString { ~"" } - pub fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult { + fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult { Ok(()) } - pub fn LongDesc(&self) -> DOMString { + fn LongDesc(&self) -> DOMString { ~"" } - pub fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult { + fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult { Ok(()) } - pub fn NoResize(&self) -> bool { + fn NoResize(&self) -> bool { false } - pub fn SetNoResize(&mut self, _no_resize: bool) -> ErrorResult { + fn SetNoResize(&mut self, _no_resize: bool) -> ErrorResult { Ok(()) } - pub fn GetContentDocument(&self) -> Option<JS<Document>> { + fn GetContentDocument(&self) -> Option<Temporary<Document>> { None } - pub fn GetContentWindow(&self) -> Option<JS<Window>> { + fn GetContentWindow(&self) -> Option<Temporary<Window>> { None } - pub fn MarginHeight(&self) -> DOMString { + fn MarginHeight(&self) -> DOMString { ~"" } - pub fn SetMarginHeight(&mut self, _height: DOMString) -> ErrorResult { + fn SetMarginHeight(&mut self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn MarginWidth(&self) -> DOMString { + fn MarginWidth(&self) -> DOMString { ~"" } - pub fn SetMarginWidth(&mut self, _height: DOMString) -> ErrorResult { + fn SetMarginWidth(&mut self, _height: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlframesetelement.rs b/src/components/script/dom/htmlframesetelement.rs index 3d7297ca6ec..c9effdd7e2e 100644 --- a/src/components/script/dom/htmlframesetelement.rs +++ b/src/components/script/dom/htmlframesetelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLFrameSetElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFrameSetElementTypeId; @@ -28,32 +28,39 @@ impl HTMLFrameSetElementDerived for EventTarget { } impl HTMLFrameSetElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameSetElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFrameSetElement { HTMLFrameSetElement { htmlelement: HTMLElement::new_inherited(HTMLFrameSetElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameSetElement> { - let element = HTMLFrameSetElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFrameSetElement> { + let element = HTMLFrameSetElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLFrameSetElementBinding::Wrap) } } -impl HTMLFrameSetElement { - pub fn Cols(&self) -> DOMString { +pub trait HTMLFrameSetElementMethods { + fn Cols(&self) -> DOMString; + fn SetCols(&mut self, _cols: DOMString) -> ErrorResult; + fn Rows(&self) -> DOMString; + fn SetRows(&mut self, _rows: DOMString) -> ErrorResult; +} + +impl<'a> HTMLFrameSetElementMethods for JSRef<'a, HTMLFrameSetElement> { + fn Cols(&self) -> DOMString { ~"" } - pub fn SetCols(&mut self, _cols: DOMString) -> ErrorResult { + fn SetCols(&mut self, _cols: DOMString) -> ErrorResult { Ok(()) } - pub fn Rows(&self) -> DOMString { + fn Rows(&self) -> DOMString { ~"" } - pub fn SetRows(&mut self, _rows: DOMString) -> ErrorResult { + fn SetRows(&mut self, _rows: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlheadelement.rs b/src/components/script/dom/htmlheadelement.rs index bf0b3f3d9b8..542312c9dfe 100644 --- a/src/components/script/dom/htmlheadelement.rs +++ b/src/components/script/dom/htmlheadelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLHeadElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHeadElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLHeadElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLHeadElementDerived for EventTarget { } impl HTMLHeadElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHeadElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLHeadElement { HTMLHeadElement { htmlelement: HTMLElement::new_inherited(HTMLHeadElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHeadElement> { - let element = HTMLHeadElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLHeadElement> { + let element = HTMLHeadElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLHeadElementBinding::Wrap) } } + +pub trait HTMLHeadElementMethods { +} diff --git a/src/components/script/dom/htmlheadingelement.rs b/src/components/script/dom/htmlheadingelement.rs index 5bf9ac39f55..7da612ab81e 100644 --- a/src/components/script/dom/htmlheadingelement.rs +++ b/src/components/script/dom/htmlheadingelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLHeadingElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLHeadingElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -38,24 +38,29 @@ impl HTMLHeadingElementDerived for EventTarget { } impl HTMLHeadingElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>, level: HeadingLevel) -> HTMLHeadingElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>, level: HeadingLevel) -> HTMLHeadingElement { HTMLHeadingElement { htmlelement: HTMLElement::new_inherited(HTMLHeadingElementTypeId, localName, document), level: level, } } - pub fn new(localName: DOMString, document: &JS<Document>, level: HeadingLevel) -> JS<HTMLHeadingElement> { - let element = HTMLHeadingElement::new_inherited(localName, document.clone(), level); + pub fn new(localName: DOMString, document: &JSRef<Document>, level: HeadingLevel) -> Temporary<HTMLHeadingElement> { + let element = HTMLHeadingElement::new_inherited(localName, document, level); Node::reflect_node(~element, document, HTMLHeadingElementBinding::Wrap) } } -impl HTMLHeadingElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLHeadingElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString); +} + +impl<'a> HTMLHeadingElementMethods for JSRef<'a, HTMLHeadingElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) { + fn SetAlign(&mut self, _align: DOMString) { } } diff --git a/src/components/script/dom/htmlhrelement.rs b/src/components/script/dom/htmlhrelement.rs index 25315450c5a..b140486165a 100644 --- a/src/components/script/dom/htmlhrelement.rs +++ b/src/components/script/dom/htmlhrelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLHRElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLHRElementTypeId; @@ -28,56 +28,69 @@ impl HTMLHRElementDerived for EventTarget { } impl HTMLHRElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHRElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLHRElement { HTMLHRElement { htmlelement: HTMLElement::new_inherited(HTMLHRElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHRElement> { - let element = HTMLHRElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLHRElement> { + let element = HTMLHRElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLHRElementBinding::Wrap) } } -impl HTMLHRElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLHRElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Color(&self) -> DOMString; + fn SetColor(&mut self, _color: DOMString) -> ErrorResult; + fn NoShade(&self) -> bool; + fn SetNoShade(&self, _no_shade: bool) -> ErrorResult; + fn Size(&self) -> DOMString; + fn SetSize(&mut self, _size: DOMString) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; +} + +impl<'a> HTMLHRElementMethods for JSRef<'a, HTMLHRElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Color(&self) -> DOMString { + fn Color(&self) -> DOMString { ~"" } - pub fn SetColor(&mut self, _color: DOMString) -> ErrorResult { + fn SetColor(&mut self, _color: DOMString) -> ErrorResult { Ok(()) } - pub fn NoShade(&self) -> bool { + fn NoShade(&self) -> bool { false } - pub fn SetNoShade(&self, _no_shade: bool) -> ErrorResult { + fn SetNoShade(&self, _no_shade: bool) -> ErrorResult { Ok(()) } - pub fn Size(&self) -> DOMString { + fn Size(&self) -> DOMString { ~"" } - pub fn SetSize(&mut self, _size: DOMString) -> ErrorResult { + fn SetSize(&mut self, _size: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlhtmlelement.rs b/src/components/script/dom/htmlhtmlelement.rs index b88639b3c59..27ca473e3a2 100644 --- a/src/components/script/dom/htmlhtmlelement.rs +++ b/src/components/script/dom/htmlhtmlelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLHtmlElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLHtmlElementTypeId; @@ -28,24 +28,29 @@ impl HTMLHtmlElementDerived for EventTarget { } impl HTMLHtmlElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHtmlElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLHtmlElement { HTMLHtmlElement { htmlelement: HTMLElement::new_inherited(HTMLHtmlElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHtmlElement> { - let element = HTMLHtmlElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLHtmlElement> { + let element = HTMLHtmlElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLHtmlElementBinding::Wrap) } } -impl HTMLHtmlElement { - pub fn Version(&self) -> DOMString { +pub trait HTMLHtmlElementMethods { + fn Version(&self) -> DOMString; + fn SetVersion(&mut self, _version: DOMString) -> ErrorResult; +} + +impl<'a> HTMLHtmlElementMethods for JSRef<'a, HTMLHtmlElement> { + fn Version(&self) -> DOMString { ~"" } - pub fn SetVersion(&mut self, _version: DOMString) -> ErrorResult { + fn SetVersion(&mut self, _version: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index 99ddf3d30f2..31c2981a5e1 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLIFrameElementBinding; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived, HTMLElementCast}; use dom::bindings::error::ErrorResult; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{HTMLIFrameElementTypeId, Element}; @@ -54,18 +54,23 @@ pub struct IFrameSize { pub subpage_id: SubpageId, } -impl HTMLIFrameElement { - pub fn is_sandboxed(&self) -> bool { +pub trait HTMLIFrameElementHelpers { + fn is_sandboxed(&self) -> bool; + fn set_frame(&mut self, frame: Url); +} + +impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { + fn is_sandboxed(&self) -> bool { self.sandbox.is_some() } - pub fn set_frame(&mut self, frame: Url) { + fn set_frame(&mut self, frame: Url) { *self.frame = Some(frame); } } impl HTMLIFrameElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLIFrameElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(HTMLIFrameElementTypeId, localName, document), frame: Untraceable::new(None), @@ -74,136 +79,168 @@ impl HTMLIFrameElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLIFrameElement> { - let element = HTMLIFrameElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLIFrameElement> { + let element = HTMLIFrameElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLIFrameElementBinding::Wrap) } } -impl HTMLIFrameElement { - pub fn Src(&self) -> DOMString { +pub trait HTMLIFrameElementMethods { + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Srcdoc(&self) -> DOMString; + fn SetSrcdoc(&mut self, _srcdoc: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Sandbox(&self) -> DOMString; + fn SetSandbox(&mut self, sandbox: DOMString); + fn AllowFullscreen(&self) -> bool; + fn SetAllowFullscreen(&mut self, _allow: bool) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; + fn Height(&self) -> DOMString; + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult; + fn GetContentDocument(&self) -> Option<Temporary<Document>>; + fn GetContentWindow(&self) -> Option<Temporary<Window>>; + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Scrolling(&self) -> DOMString; + fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult; + fn FrameBorder(&self) -> DOMString; + fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult; + fn LongDesc(&self) -> DOMString; + fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult; + fn MarginHeight(&self) -> DOMString; + fn SetMarginHeight(&mut self, _marginheight: DOMString) -> ErrorResult; + fn MarginWidth(&self) -> DOMString; + fn SetMarginWidth(&mut self, _marginwidth: DOMString) -> ErrorResult; + fn GetSVGDocument(&self) -> Option<Temporary<Document>>; +} + +impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Srcdoc(&self) -> DOMString { + fn Srcdoc(&self) -> DOMString { ~"" } - pub fn SetSrcdoc(&mut self, _srcdoc: DOMString) -> ErrorResult { + fn SetSrcdoc(&mut self, _srcdoc: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Sandbox(&self, abstract_self: &JS<HTMLIFrameElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Sandbox(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("sandbox") } - pub fn SetSandbox(&mut self, abstract_self: &mut JS<HTMLIFrameElement>, sandbox: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetSandbox(&mut self, sandbox: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("sandbox", sandbox); } - pub fn AllowFullscreen(&self) -> bool { + fn AllowFullscreen(&self) -> bool { false } - pub fn SetAllowFullscreen(&mut self, _allow: bool) -> ErrorResult { + fn SetAllowFullscreen(&mut self, _allow: bool) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> DOMString { + fn Height(&self) -> DOMString { ~"" } - pub fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn GetContentDocument(&self) -> Option<JS<Document>> { + fn GetContentDocument(&self) -> Option<Temporary<Document>> { None } - pub fn GetContentWindow(&self) -> Option<JS<Window>> { + fn GetContentWindow(&self) -> Option<Temporary<Window>> { None } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Scrolling(&self) -> DOMString { + fn Scrolling(&self) -> DOMString { ~"" } - pub fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult { + fn SetScrolling(&mut self, _scrolling: DOMString) -> ErrorResult { Ok(()) } - pub fn FrameBorder(&self) -> DOMString { + fn FrameBorder(&self) -> DOMString { ~"" } - pub fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult { + fn SetFrameBorder(&mut self, _frameborder: DOMString) -> ErrorResult { Ok(()) } - pub fn LongDesc(&self) -> DOMString { + fn LongDesc(&self) -> DOMString { ~"" } - pub fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult { + fn SetLongDesc(&mut self, _longdesc: DOMString) -> ErrorResult { Ok(()) } - pub fn MarginHeight(&self) -> DOMString { + fn MarginHeight(&self) -> DOMString { ~"" } - pub fn SetMarginHeight(&mut self, _marginheight: DOMString) -> ErrorResult { + fn SetMarginHeight(&mut self, _marginheight: DOMString) -> ErrorResult { Ok(()) } - pub fn MarginWidth(&self) -> DOMString { + fn MarginWidth(&self) -> DOMString { ~"" } - pub fn SetMarginWidth(&mut self, _marginwidth: DOMString) -> ErrorResult { + fn SetMarginWidth(&mut self, _marginwidth: DOMString) -> ErrorResult { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<JS<Document>> { + fn GetSVGDocument(&self) -> Option<Temporary<Document>> { None } } -impl VirtualMethods for JS<HTMLIFrameElement> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self); - Some(~htmlelement as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self); + Some(htmlelement as &mut VirtualMethods:) } fn after_set_attr(&mut self, name: DOMString, value: DOMString) { @@ -227,7 +264,7 @@ impl VirtualMethods for JS<HTMLIFrameElement> { _ => AllowNothing } as u8; } - self.get_mut().sandbox = Some(modes); + self.deref_mut().sandbox = Some(modes); } } @@ -238,7 +275,7 @@ impl VirtualMethods for JS<HTMLIFrameElement> { } if "sandbox" == name { - self.get_mut().sandbox = None; + self.deref_mut().sandbox = None; } } } diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 6bb7096fcde..c3a60874c6d 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLImageElementBinding; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived}; use dom::bindings::error::ErrorResult; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{Element, HTMLImageElementTypeId}; @@ -35,31 +35,18 @@ impl HTMLImageElementDerived for EventTarget { } } -impl HTMLImageElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLImageElement { - HTMLImageElement { - htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document), - image: Untraceable::new(None), - } - } - - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLImageElement> { - let element = HTMLImageElement::new_inherited(localName, document.clone()); - Node::reflect_node(~element, document, HTMLImageElementBinding::Wrap) - } +trait PrivateHTMLImageElementHelpers { + fn update_image(&mut self, value: Option<DOMString>, url: Option<Url>); } -impl HTMLImageElement { - pub fn image<'a>(&'a self) -> &'a Option<Url> { - &*self.image - } - +impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> { /// Makes the local `image` member match the status of the `src` attribute and starts /// prefetching the image. This method must be called after `src` is changed. fn update_image(&mut self, value: Option<DOMString>, url: Option<Url>) { - let elem = &mut self.htmlelement.element; - let document = elem.node.owner_doc(); - let window = document.get().window.get(); + let self_alias = self.clone(); + let node_alias: &JSRef<Node> = NodeCast::from_ref(&self_alias); + let document = node_alias.owner_doc().root(); + let window = document.deref().window.root(); let image_cache = &window.image_cache_task; match value { None => { @@ -78,154 +65,212 @@ impl HTMLImageElement { } } } +} + +impl HTMLImageElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLImageElement { + HTMLImageElement { + htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document), + image: Untraceable::new(None), + } + } + + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLImageElement> { + let element = HTMLImageElement::new_inherited(localName, document); + Node::reflect_node(~element, document, HTMLImageElementBinding::Wrap) + } +} + +pub trait LayoutHTMLImageElementHelpers { + unsafe fn image<'a>(&'a self) -> &'a Option<Url>; +} + +impl LayoutHTMLImageElementHelpers for JS<HTMLImageElement> { + unsafe fn image<'a>(&'a self) -> &'a Option<Url> { + &*(*self.unsafe_get()).image + } +} + +pub trait HTMLImageElementMethods { + fn Alt(&self) -> DOMString; + fn SetAlt(&mut self, alt: DOMString); + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, src: DOMString); + fn CrossOrigin(&self) -> DOMString; + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult; + fn UseMap(&self) -> DOMString; + fn SetUseMap(&mut self, use_map: DOMString); + fn IsMap(&self) -> bool; + fn SetIsMap(&mut self, is_map: bool); + fn Width(&self) -> u32; + fn SetWidth(&mut self, width: u32); + fn Height(&self) -> u32; + fn SetHeight(&mut self, height: u32); + fn NaturalWidth(&self) -> u32; + fn NaturalHeight(&self) -> u32; + fn Complete(&self) -> bool; + fn Name(&self) -> DOMString; + fn SetName(&mut self, name: DOMString); + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, align: DOMString); + fn Hspace(&self) -> u32; + fn SetHspace(&mut self, hspace: u32); + fn Vspace(&self) -> u32; + fn SetVspace(&mut self, vspace: u32); + fn LongDesc(&self) -> DOMString; + fn SetLongDesc(&mut self, longdesc: DOMString); + fn Border(&self) -> DOMString; + fn SetBorder(&mut self, border: DOMString); +} - pub fn Alt(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); +impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { + fn Alt(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("alt") } - pub fn SetAlt(&mut self, abstract_self: &JS<HTMLImageElement>, alt: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetAlt(&mut self, alt: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("alt", alt) } - pub fn Src(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Src(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("src") } - pub fn SetSrc(&mut self, abstract_self: &mut JS<HTMLImageElement>, src: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetSrc(&mut self, src: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_url_attribute("src", src) } - pub fn CrossOrigin(&self) -> DOMString { + fn CrossOrigin(&self) -> DOMString { ~"" } - pub fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { Ok(()) } - pub fn UseMap(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn UseMap(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("useMap") } - pub fn SetUseMap(&mut self, abstract_self: &mut JS<HTMLImageElement>, use_map: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetUseMap(&mut self, use_map: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("useMap", use_map) } - pub fn IsMap(&self, abstract_self: &JS<HTMLImageElement>) -> bool { - let element: JS<Element> = ElementCast::from(abstract_self); + fn IsMap(&self) -> bool { + let element: &JSRef<Element> = ElementCast::from_ref(self); from_str::<bool>(element.get_string_attribute("hspace")).unwrap() } - pub fn SetIsMap(&self, abstract_self: &mut JS<HTMLImageElement>, is_map: bool) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetIsMap(&mut self, is_map: bool) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("isMap", is_map.to_str()) } - pub fn Width(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let node: JS<Node> = NodeCast::from(abstract_self); + fn Width(&self) -> u32 { + let node: &JSRef<Node> = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); to_px(rect.size.width) as u32 } - pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) { - let mut elem: JS<Element> = ElementCast::from(abstract_self); + fn SetWidth(&mut self, width: u32) { + let elem: &mut JSRef<Element> = ElementCast::from_mut_ref(self); elem.set_uint_attribute("width", width) } - pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let node: JS<Node> = NodeCast::from(abstract_self); + fn Height(&self) -> u32 { + let node: &JSRef<Node> = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); to_px(rect.size.height) as u32 } - pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) { - let mut elem: JS<Element> = ElementCast::from(abstract_self); + fn SetHeight(&mut self, height: u32) { + let elem: &mut JSRef<Element> = ElementCast::from_mut_ref(self); elem.set_uint_attribute("height", height) } - pub fn NaturalWidth(&self) -> u32 { + fn NaturalWidth(&self) -> u32 { 0 } - pub fn NaturalHeight(&self) -> u32 { + fn NaturalHeight(&self) -> u32 { 0 } - pub fn Complete(&self) -> bool { + fn Complete(&self) -> bool { false } - pub fn Name(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Name(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("name") } - pub fn SetName(&mut self, abstract_self: &mut JS<HTMLImageElement>, name: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetName(&mut self, name: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("name", name) } - pub fn Align(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); - element.get_string_attribute("longdesc") + fn Align(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); + element.get_string_attribute("align") } - pub fn SetAlign(&mut self, abstract_self: &mut JS<HTMLImageElement>, align: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetAlign(&mut self, align: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("align", align) } - pub fn Hspace(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Hspace(&self) -> u32 { + let element: &JSRef<Element> = ElementCast::from_ref(self); from_str::<u32>(element.get_string_attribute("hspace")).unwrap() } - pub fn SetHspace(&mut self, abstract_self: &mut JS<HTMLImageElement>, hspace: u32) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetHspace(&mut self, hspace: u32) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_uint_attribute("hspace", hspace) } - pub fn Vspace(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Vspace(&self) -> u32 { + let element: &JSRef<Element> = ElementCast::from_ref(self); from_str::<u32>(element.get_string_attribute("vspace")).unwrap() } - pub fn SetVspace(&mut self, abstract_self: &mut JS<HTMLImageElement>, vspace: u32) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetVspace(&mut self, vspace: u32) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_uint_attribute("vspace", vspace) } - pub fn LongDesc(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn LongDesc(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("longdesc") } - pub fn SetLongDesc(&mut self, abstract_self: &mut JS<HTMLImageElement>, longdesc: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetLongDesc(&mut self, longdesc: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("longdesc", longdesc) } - pub fn Border(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + fn Border(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_string_attribute("border") } - pub fn SetBorder(&mut self, abstract_self: &mut JS<HTMLImageElement>, border: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + fn SetBorder(&mut self, border: DOMString) { + let element: &mut JSRef<Element> = ElementCast::from_mut_ref(self); element.set_string_attribute("border", border) } } -impl VirtualMethods for JS<HTMLImageElement> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self); - Some(~htmlelement as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self); + Some(htmlelement as &mut VirtualMethods:) } fn after_set_attr(&mut self, name: DOMString, value: DOMString) { @@ -235,9 +280,9 @@ impl VirtualMethods for JS<HTMLImageElement> { } if "src" == name { - let window = window_from_node(self); - let url = Some(window.get().get_url()); - self.get_mut().update_image(Some(value), url); + let window = window_from_node(self).root(); + let url = Some(window.deref().get_url()); + self.update_image(Some(value), url); } } @@ -248,7 +293,7 @@ impl VirtualMethods for JS<HTMLImageElement> { } if "src" == name { - self.get_mut().update_image(None, None); + self.update_image(None, None); } } } diff --git a/src/components/script/dom/htmlinputelement.rs b/src/components/script/dom/htmlinputelement.rs index 978ce8a0d63..f75ef6c248c 100644 --- a/src/components/script/dom/htmlinputelement.rs +++ b/src/components/script/dom/htmlinputelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLInputElementBinding; use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLInputElementTypeId; @@ -28,322 +28,403 @@ impl HTMLInputElementDerived for EventTarget { } impl HTMLInputElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLInputElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLInputElement { HTMLInputElement { htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLInputElement> { - let element = HTMLInputElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLInputElement> { + let element = HTMLInputElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLInputElementBinding::Wrap) } } -impl HTMLInputElement { - pub fn Accept(&self) -> DOMString { +pub trait HTMLInputElementMethods { + fn Accept(&self) -> DOMString; + fn SetAccept(&mut self, _accept: DOMString) -> ErrorResult; + fn Alt(&self) -> DOMString; + fn SetAlt(&mut self, _alt: DOMString) -> ErrorResult; + fn Autocomplete(&self) -> DOMString; + fn SetAutocomplete(&mut self, _autocomple: DOMString) -> ErrorResult; + fn Autofocus(&self) -> bool; + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult; + fn DefaultChecked(&self) -> bool; + fn SetDefaultChecked(&mut self, _default_checked: bool) -> ErrorResult; + fn Checked(&self) -> bool; + fn SetChecked(&mut self, _checked: bool); + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn FormAction(&self) -> DOMString; + fn SetFormAction(&mut self, _form_action: DOMString) -> ErrorResult; + fn FormEnctype(&self) -> DOMString; + fn SetFormEnctype(&mut self, _form_enctype: DOMString) -> ErrorResult; + fn FormMethod(&self) -> DOMString; + fn SetFormMethod(&mut self, _form_method: DOMString) -> ErrorResult; + fn FormNoValidate(&self) -> bool; + fn SetFormNoValidate(&mut self, _form_no_validate: bool) -> ErrorResult; + fn FormTarget(&self) -> DOMString; + fn SetFormTarget(&mut self, _form_target: DOMString) -> ErrorResult; + fn Height(&self) -> u32; + fn SetHeight(&mut self, _height: u32) -> ErrorResult; + fn Indeterminate(&self) -> bool; + fn SetIndeterminate(&mut self, _indeterminate: bool); + fn InputMode(&self) -> DOMString; + fn SetInputMode(&mut self, _input_mode: DOMString) -> ErrorResult; + fn Max(&self) -> DOMString; + fn SetMax(&mut self, _max: DOMString) -> ErrorResult; + fn MaxLength(&self) -> i32; + fn SetMaxLength(&mut self, _max_length: i32) -> ErrorResult; + fn Min(&self) -> DOMString; + fn SetMin(&mut self, _min: DOMString) -> ErrorResult; + fn Multiple(&self) -> bool; + fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Pattern(&self) -> DOMString; + fn SetPattern(&mut self, _pattern: DOMString) -> ErrorResult; + fn Placeholder(&self) -> DOMString; + fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult; + fn ReadOnly(&self) -> bool; + fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult; + fn Required(&self) -> bool; + fn SetRequired(&mut self, _required: bool) -> ErrorResult; + fn Size(&self) -> u32; + fn SetSize(&mut self, _size: u32) -> ErrorResult; + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Step(&self) -> DOMString; + fn SetStep(&mut self, _step: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn DefaultValue(&self) -> DOMString; + fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; + fn Width(&self) -> u32; + fn SetWidth(&mut self, _width: u32); + fn WillValidate(&self) -> bool; + fn SetWillValidate(&self, _will_validate: bool); + fn GetValidationMessage(&self) -> Fallible<DOMString>; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&self, _error: DOMString); + fn Select(&self); + fn GetSelectionStart(&self) -> Fallible<i32>; + fn SetSelectionStart(&mut self, _selection_start: i32) -> ErrorResult; + fn GetSelectionEnd(&self) -> Fallible<i32>; + fn SetSelectionEnd(&mut self, _selection_end: i32) -> ErrorResult; + fn GetSelectionDirection(&self) -> Fallible<DOMString>; + fn SetSelectionDirection(&mut self, _selection_direction: DOMString) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn UseMap(&self) -> DOMString; + fn SetUseMap(&mut self, _align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { + fn Accept(&self) -> DOMString { ~"" } - pub fn SetAccept(&mut self, _accept: DOMString) -> ErrorResult { + fn SetAccept(&mut self, _accept: DOMString) -> ErrorResult { Ok(()) } - pub fn Alt(&self) -> DOMString { + fn Alt(&self) -> DOMString { ~"" } - pub fn SetAlt(&mut self, _alt: DOMString) -> ErrorResult { + fn SetAlt(&mut self, _alt: DOMString) -> ErrorResult { Ok(()) } - pub fn Autocomplete(&self) -> DOMString { + fn Autocomplete(&self) -> DOMString { ~"" } - pub fn SetAutocomplete(&mut self, _autocomple: DOMString) -> ErrorResult { + fn SetAutocomplete(&mut self, _autocomple: DOMString) -> ErrorResult { Ok(()) } - pub fn Autofocus(&self) -> bool { + fn Autofocus(&self) -> bool { false } - pub fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { Ok(()) } - pub fn DefaultChecked(&self) -> bool { + fn DefaultChecked(&self) -> bool { false } - pub fn SetDefaultChecked(&mut self, _default_checked: bool) -> ErrorResult { + fn SetDefaultChecked(&mut self, _default_checked: bool) -> ErrorResult { Ok(()) } - pub fn Checked(&self) -> bool { + fn Checked(&self) -> bool { false } - pub fn SetChecked(&mut self, _checked: bool) { + fn SetChecked(&mut self, _checked: bool) { } - pub fn Disabled(&self) -> bool { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn FormAction(&self) -> DOMString { + fn FormAction(&self) -> DOMString { ~"" } - pub fn SetFormAction(&mut self, _form_action: DOMString) -> ErrorResult { + fn SetFormAction(&mut self, _form_action: DOMString) -> ErrorResult { Ok(()) } - pub fn FormEnctype(&self) -> DOMString { + fn FormEnctype(&self) -> DOMString { ~"" } - pub fn SetFormEnctype(&mut self, _form_enctype: DOMString) -> ErrorResult { + fn SetFormEnctype(&mut self, _form_enctype: DOMString) -> ErrorResult { Ok(()) } - pub fn FormMethod(&self) -> DOMString { + fn FormMethod(&self) -> DOMString { ~"" } - pub fn SetFormMethod(&mut self, _form_method: DOMString) -> ErrorResult { + fn SetFormMethod(&mut self, _form_method: DOMString) -> ErrorResult { Ok(()) } - pub fn FormNoValidate(&self) -> bool { + fn FormNoValidate(&self) -> bool { false } - pub fn SetFormNoValidate(&mut self, _form_no_validate: bool) -> ErrorResult { + fn SetFormNoValidate(&mut self, _form_no_validate: bool) -> ErrorResult { Ok(()) } - pub fn FormTarget(&self) -> DOMString { + fn FormTarget(&self) -> DOMString { ~"" } - pub fn SetFormTarget(&mut self, _form_target: DOMString) -> ErrorResult { + fn SetFormTarget(&mut self, _form_target: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> u32 { + fn Height(&self) -> u32 { 0 } - pub fn SetHeight(&mut self, _height: u32) -> ErrorResult { + fn SetHeight(&mut self, _height: u32) -> ErrorResult { Ok(()) } - pub fn Indeterminate(&self) -> bool { + fn Indeterminate(&self) -> bool { false } - pub fn SetIndeterminate(&mut self, _indeterminate: bool) { + fn SetIndeterminate(&mut self, _indeterminate: bool) { } - pub fn InputMode(&self) -> DOMString { + fn InputMode(&self) -> DOMString { ~"" } - pub fn SetInputMode(&mut self, _input_mode: DOMString) -> ErrorResult { + fn SetInputMode(&mut self, _input_mode: DOMString) -> ErrorResult { Ok(()) } - pub fn Max(&self) -> DOMString { + fn Max(&self) -> DOMString { ~"" } - pub fn SetMax(&mut self, _max: DOMString) -> ErrorResult { + fn SetMax(&mut self, _max: DOMString) -> ErrorResult { Ok(()) } - pub fn MaxLength(&self) -> i32 { + fn MaxLength(&self) -> i32 { 0 } - pub fn SetMaxLength(&mut self, _max_length: i32) -> ErrorResult { + fn SetMaxLength(&mut self, _max_length: i32) -> ErrorResult { Ok(()) } - pub fn Min(&self) -> DOMString { + fn Min(&self) -> DOMString { ~"" } - pub fn SetMin(&mut self, _min: DOMString) -> ErrorResult { + fn SetMin(&mut self, _min: DOMString) -> ErrorResult { Ok(()) } - pub fn Multiple(&self) -> bool { + fn Multiple(&self) -> bool { false } - pub fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult { + fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Pattern(&self) -> DOMString { + fn Pattern(&self) -> DOMString { ~"" } - pub fn SetPattern(&mut self, _pattern: DOMString) -> ErrorResult { + fn SetPattern(&mut self, _pattern: DOMString) -> ErrorResult { Ok(()) } - pub fn Placeholder(&self) -> DOMString { + fn Placeholder(&self) -> DOMString { ~"" } - pub fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult { + fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult { Ok(()) } - pub fn ReadOnly(&self) -> bool { + fn ReadOnly(&self) -> bool { false } - pub fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult { + fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult { Ok(()) } - pub fn Required(&self) -> bool { + fn Required(&self) -> bool { false } - pub fn SetRequired(&mut self, _required: bool) -> ErrorResult { + fn SetRequired(&mut self, _required: bool) -> ErrorResult { Ok(()) } - pub fn Size(&self) -> u32 { + fn Size(&self) -> u32 { 0 } - pub fn SetSize(&mut self, _size: u32) -> ErrorResult { + fn SetSize(&mut self, _size: u32) -> ErrorResult { Ok(()) } - pub fn Src(&self) -> DOMString { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Step(&self) -> DOMString { + fn Step(&self) -> DOMString { ~"" } - pub fn SetStep(&mut self, _step: DOMString) -> ErrorResult { + fn SetStep(&mut self, _step: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn DefaultValue(&self) -> DOMString { + fn DefaultValue(&self) -> DOMString { ~"" } - pub fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult { + fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> u32 { + fn Width(&self) -> u32 { 0 } - pub fn SetWidth(&mut self, _width: u32) { + fn SetWidth(&mut self, _width: u32) { } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn SetWillValidate(&self, _will_validate: bool) { + fn SetWillValidate(&self, _will_validate: bool) { } - pub fn GetValidationMessage(&self) -> Fallible<DOMString> { + fn GetValidationMessage(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { false } - pub fn SetCustomValidity(&self, _error: DOMString) { + fn SetCustomValidity(&self, _error: DOMString) { } - pub fn Select(&self) { + fn Select(&self) { } - pub fn GetSelectionStart(&self) -> Fallible<i32> { + fn GetSelectionStart(&self) -> Fallible<i32> { Ok(0) } - pub fn SetSelectionStart(&mut self, _selection_start: i32) -> ErrorResult { + fn SetSelectionStart(&mut self, _selection_start: i32) -> ErrorResult { Ok(()) } - pub fn GetSelectionEnd(&self) -> Fallible<i32> { + fn GetSelectionEnd(&self) -> Fallible<i32> { Ok(0) } - pub fn SetSelectionEnd(&mut self, _selection_end: i32) -> ErrorResult { + fn SetSelectionEnd(&mut self, _selection_end: i32) -> ErrorResult { Ok(()) } - pub fn GetSelectionDirection(&self) -> Fallible<DOMString> { + fn GetSelectionDirection(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn SetSelectionDirection(&mut self, _selection_direction: DOMString) -> ErrorResult { + fn SetSelectionDirection(&mut self, _selection_direction: DOMString) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn UseMap(&self) -> DOMString { + fn UseMap(&self) -> DOMString { ~"" } - pub fn SetUseMap(&mut self, _align: DOMString) -> ErrorResult { + fn SetUseMap(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmllabelelement.rs b/src/components/script/dom/htmllabelelement.rs index 70c811c949e..9c53ec073b4 100644 --- a/src/components/script/dom/htmllabelelement.rs +++ b/src/components/script/dom/htmllabelelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLLabelElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLLabelElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,23 +27,28 @@ impl HTMLLabelElementDerived for EventTarget { } impl HTMLLabelElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLabelElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLLabelElement { HTMLLabelElement { htmlelement: HTMLElement::new_inherited(HTMLLabelElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLabelElement> { - let element = HTMLLabelElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLLabelElement> { + let element = HTMLLabelElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLLabelElementBinding::Wrap) } } -impl HTMLLabelElement { - pub fn HtmlFor(&self) -> DOMString { +pub trait HTMLLabelElementMethods { + fn HtmlFor(&self) -> DOMString; + fn SetHtmlFor(&mut self, _html_for: DOMString); +} + +impl<'a> HTMLLabelElementMethods for JSRef<'a, HTMLLabelElement> { + fn HtmlFor(&self) -> DOMString { ~"" } - pub fn SetHtmlFor(&mut self, _html_for: DOMString) { + fn SetHtmlFor(&mut self, _html_for: DOMString) { } } diff --git a/src/components/script/dom/htmllegendelement.rs b/src/components/script/dom/htmllegendelement.rs index a8fdf6a1405..ad7653e6424 100644 --- a/src/components/script/dom/htmllegendelement.rs +++ b/src/components/script/dom/htmllegendelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLLegendElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLegendElementTypeId; @@ -28,24 +28,29 @@ impl HTMLLegendElementDerived for EventTarget { } impl HTMLLegendElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLegendElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLLegendElement { HTMLLegendElement { htmlelement: HTMLElement::new_inherited(HTMLLegendElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLegendElement> { - let element = HTMLLegendElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLLegendElement> { + let element = HTMLLegendElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLLegendElementBinding::Wrap) } } -impl HTMLLegendElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLLegendElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLLegendElementMethods for JSRef<'a, HTMLLegendElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmllielement.rs b/src/components/script/dom/htmllielement.rs index 052557545ea..de85baea7f3 100644 --- a/src/components/script/dom/htmllielement.rs +++ b/src/components/script/dom/htmllielement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLLIElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLIElementTypeId; @@ -28,32 +28,39 @@ impl HTMLLIElementDerived for EventTarget { } impl HTMLLIElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLIElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLLIElement { HTMLLIElement { htmlelement: HTMLElement::new_inherited(HTMLLIElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLIElement> { - let element = HTMLLIElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLLIElement> { + let element = HTMLLIElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLLIElementBinding::Wrap) } } -impl HTMLLIElement { - pub fn Value(&self) -> i32 { +pub trait HTMLLIElementMethods { + fn Value(&self) -> i32; + fn SetValue(&mut self, _value: i32) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; +} + +impl<'a> HTMLLIElementMethods for JSRef<'a, HTMLLIElement> { + fn Value(&self) -> i32 { 0 } - pub fn SetValue(&mut self, _value: i32) -> ErrorResult { + fn SetValue(&mut self, _value: i32) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmllinkelement.rs b/src/components/script/dom/htmllinkelement.rs index ae47e5168a2..c620526bfa1 100644 --- a/src/components/script/dom/htmllinkelement.rs +++ b/src/components/script/dom/htmllinkelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLLinkElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLinkElementTypeId; @@ -28,95 +28,118 @@ impl HTMLLinkElementDerived for EventTarget { } impl HTMLLinkElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLinkElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLLinkElement { HTMLLinkElement { htmlelement: HTMLElement::new_inherited(HTMLLinkElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLinkElement> { - let element = HTMLLinkElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLLinkElement> { + let element = HTMLLinkElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLLinkElementBinding::Wrap) } } -impl HTMLLinkElement { - pub fn Disabled(&self) -> bool { +pub trait HTMLLinkElementMethods { + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disable: bool); + fn Href(&self) -> DOMString; + fn SetHref(&mut self, _href: DOMString) -> ErrorResult; + fn CrossOrigin(&self) -> DOMString; + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult; + fn Rel(&self) -> DOMString; + fn SetRel(&mut self, _rel: DOMString) -> ErrorResult; + fn Media(&self) -> DOMString; + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult; + fn Hreflang(&self) -> DOMString; + fn SetHreflang(&mut self, _href: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Charset(&self) -> DOMString; + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult; + fn Rev(&self) -> DOMString; + fn SetRev(&mut self, _rev: DOMString) -> ErrorResult; + fn Target(&self) -> DOMString; + fn SetTarget(&mut self, _target: DOMString) -> ErrorResult; +} + +impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disable: bool) { + fn SetDisabled(&mut self, _disable: bool) { } - pub fn Href(&self) -> DOMString { + fn Href(&self) -> DOMString { ~"" } - pub fn SetHref(&mut self, _href: DOMString) -> ErrorResult { + fn SetHref(&mut self, _href: DOMString) -> ErrorResult { Ok(()) } - pub fn CrossOrigin(&self) -> DOMString { + fn CrossOrigin(&self) -> DOMString { ~"" } - pub fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { Ok(()) } - pub fn Rel(&self) -> DOMString { + fn Rel(&self) -> DOMString { ~"" } - pub fn SetRel(&mut self, _rel: DOMString) -> ErrorResult { + fn SetRel(&mut self, _rel: DOMString) -> ErrorResult { Ok(()) } - pub fn Media(&self) -> DOMString { + fn Media(&self) -> DOMString { ~"" } - pub fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { Ok(()) } - pub fn Hreflang(&self) -> DOMString { + fn Hreflang(&self) -> DOMString { ~"" } - pub fn SetHreflang(&mut self, _href: DOMString) -> ErrorResult { + fn SetHreflang(&mut self, _href: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Charset(&self) -> DOMString { + fn Charset(&self) -> DOMString { ~"" } - pub fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { Ok(()) } - pub fn Rev(&self) -> DOMString { + fn Rev(&self) -> DOMString { ~"" } - pub fn SetRev(&mut self, _rev: DOMString) -> ErrorResult { + fn SetRev(&mut self, _rev: DOMString) -> ErrorResult { Ok(()) } - pub fn Target(&self) -> DOMString { + fn Target(&self) -> DOMString { ~"" } - pub fn SetTarget(&mut self, _target: DOMString) -> ErrorResult { + fn SetTarget(&mut self, _target: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlmainelement.rs b/src/components/script/dom/htmlmainelement.rs index 182a3194019..3efa0c68fb8 100644 --- a/src/components/script/dom/htmlmainelement.rs +++ b/src/components/script/dom/htmlmainelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLMainElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMainElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLMainElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLMainElementDerived for EventTarget { } impl HTMLMainElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMainElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLMainElement { HTMLMainElement { htmlelement: HTMLElement::new_inherited(HTMLMainElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMainElement> { - let element = HTMLMainElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLMainElement> { + let element = HTMLMainElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLMainElementBinding::Wrap) } } + +pub trait HTMLMainElementMethods { +} diff --git a/src/components/script/dom/htmlmapelement.rs b/src/components/script/dom/htmlmapelement.rs index 72214f0ff1d..08a6e2c5c5d 100644 --- a/src/components/script/dom/htmlmapelement.rs +++ b/src/components/script/dom/htmlmapelement.rs @@ -4,14 +4,14 @@ use dom::bindings::codegen::BindingDeclarations::HTMLMapElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMapElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::{HTMLCollection, Static}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; use servo_util::str::DOMString; #[deriving(Encodable)] @@ -29,31 +29,37 @@ impl HTMLMapElementDerived for EventTarget { } impl HTMLMapElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMapElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLMapElement { HTMLMapElement { htmlelement: HTMLElement::new_inherited(HTMLMapElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMapElement> { - let element = HTMLMapElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLMapElement> { + let element = HTMLMapElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLMapElementBinding::Wrap) } } -impl HTMLMapElement { - pub fn Name(&self) -> DOMString { +pub trait HTMLMapElementMethods { + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Areas(&self) -> Temporary<HTMLCollection>; +} + +impl<'a> HTMLMapElementMethods for JSRef<'a, HTMLMapElement> { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Areas(&self) -> JS<HTMLCollection> { + fn Areas(&self) -> Temporary<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1845 - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::new(&doc.window, Static(vec!())) + let window = window_from_node(self).root(); + HTMLCollection::new(&*window, Static(vec!())) } } + diff --git a/src/components/script/dom/htmlmediaelement.rs b/src/components/script/dom/htmlmediaelement.rs index 179c8e97407..763650008a1 100644 --- a/src/components/script/dom/htmlmediaelement.rs +++ b/src/components/script/dom/htmlmediaelement.rs @@ -2,7 +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::bindings::js::JS; +use dom::bindings::js::{JSRef}; use dom::bindings::codegen::InheritTypes::HTMLMediaElementDerived; use dom::bindings::error::ErrorResult; use dom::document::Document; @@ -28,146 +28,182 @@ impl HTMLMediaElementDerived for EventTarget { } impl HTMLMediaElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLMediaElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: &JSRef<Document>) -> HTMLMediaElement { HTMLMediaElement { htmlelement: HTMLElement::new_inherited(type_id, tag_name, document) } } } -impl HTMLMediaElement { - pub fn Src(&self) -> DOMString { +pub trait HTMLMediaElementMethods { + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn CurrentSrc(&self) -> DOMString; + fn CrossOrigin(&self) -> DOMString; + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult; + fn Preload(&self) -> DOMString; + fn SetPreload(&mut self, _preload: DOMString) -> ErrorResult; + fn Load(&self); + fn CanPlayType(&self, _type: DOMString) -> DOMString; + fn ReadyState(&self) -> u16; + fn Seeking(&self) -> bool; + fn CurrentTime(&self) -> f64; + fn SetCurrentTime(&mut self, _current_time: f64) -> ErrorResult; + fn GetDuration(&self) -> f64; + fn Paused(&self) -> bool; + fn DefaultPlaybackRate(&self) -> f64; + fn SetDefaultPlaybackRate(&mut self, _default_playback_rate: f64) -> ErrorResult; + fn PlaybackRate(&self) -> f64; + fn SetPlaybackRate(&mut self, _playback_rate: f64) -> ErrorResult; + fn Ended(&self) -> bool; + fn Autoplay(&self) -> bool; + fn SetAutoplay(&mut self, _autoplay: bool) -> ErrorResult; + fn Loop(&self) -> bool; + fn SetLoop(&mut self, _loop: bool) -> ErrorResult; + fn Play(&self) -> ErrorResult; + fn Pause(&self) -> ErrorResult; + fn Controls(&self) -> bool; + fn SetControls(&mut self, _controls: bool) -> ErrorResult; + fn Volume(&self) -> f64; + fn SetVolume(&mut self, _volume: f64) -> ErrorResult; + fn Muted(&self) -> bool; + fn SetMuted(&mut self, _muted: bool); + fn DefaultMuted(&self) -> bool; + fn SetDefaultMuted(&mut self, _default_muted: bool) -> ErrorResult; +} + +impl<'a> HTMLMediaElementMethods for JSRef<'a, HTMLMediaElement> { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn CurrentSrc(&self) -> DOMString { + fn CurrentSrc(&self) -> DOMString { ~"" } - pub fn CrossOrigin(&self) -> DOMString { + fn CrossOrigin(&self) -> DOMString { ~"" } - pub fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { Ok(()) } - pub fn Preload(&self) -> DOMString { + fn Preload(&self) -> DOMString { ~"" } - pub fn SetPreload(&mut self, _preload: DOMString) -> ErrorResult { + fn SetPreload(&mut self, _preload: DOMString) -> ErrorResult { Ok(()) } - pub fn Load(&self) { + fn Load(&self) { } - pub fn CanPlayType(&self, _type: DOMString) -> DOMString { + fn CanPlayType(&self, _type: DOMString) -> DOMString { ~"" } - pub fn ReadyState(&self) -> u16 { + fn ReadyState(&self) -> u16 { 0 } - pub fn Seeking(&self) -> bool { + fn Seeking(&self) -> bool { false } - pub fn CurrentTime(&self) -> f64 { + fn CurrentTime(&self) -> f64 { 0f64 } - pub fn SetCurrentTime(&mut self, _current_time: f64) -> ErrorResult { + fn SetCurrentTime(&mut self, _current_time: f64) -> ErrorResult { Ok(()) } - pub fn GetDuration(&self) -> f64 { + fn GetDuration(&self) -> f64 { 0f64 } - pub fn Paused(&self) -> bool { + fn Paused(&self) -> bool { false } - pub fn DefaultPlaybackRate(&self) -> f64 { + fn DefaultPlaybackRate(&self) -> f64 { 0f64 } - pub fn SetDefaultPlaybackRate(&mut self, _default_playback_rate: f64) -> ErrorResult { + fn SetDefaultPlaybackRate(&mut self, _default_playback_rate: f64) -> ErrorResult { Ok(()) } - pub fn PlaybackRate(&self) -> f64 { + fn PlaybackRate(&self) -> f64 { 0f64 } - pub fn SetPlaybackRate(&mut self, _playback_rate: f64) -> ErrorResult { + fn SetPlaybackRate(&mut self, _playback_rate: f64) -> ErrorResult { Ok(()) } - pub fn Ended(&self) -> bool { + fn Ended(&self) -> bool { false } - pub fn Autoplay(&self) -> bool { + fn Autoplay(&self) -> bool { false } - pub fn SetAutoplay(&mut self, _autoplay: bool) -> ErrorResult { + fn SetAutoplay(&mut self, _autoplay: bool) -> ErrorResult { Ok(()) } - pub fn Loop(&self) -> bool { + fn Loop(&self) -> bool { false } - pub fn SetLoop(&mut self, _loop: bool) -> ErrorResult { + fn SetLoop(&mut self, _loop: bool) -> ErrorResult { Ok(()) } - pub fn Play(&self) -> ErrorResult { + fn Play(&self) -> ErrorResult { Ok(()) } - pub fn Pause(&self) -> ErrorResult { + fn Pause(&self) -> ErrorResult { Ok(()) } - pub fn Controls(&self) -> bool { + fn Controls(&self) -> bool { false } - pub fn SetControls(&mut self, _controls: bool) -> ErrorResult { + fn SetControls(&mut self, _controls: bool) -> ErrorResult { Ok(()) } - pub fn Volume(&self) -> f64 { + fn Volume(&self) -> f64 { 0f64 } - pub fn SetVolume(&mut self, _volume: f64) -> ErrorResult { + fn SetVolume(&mut self, _volume: f64) -> ErrorResult { Ok(()) } - pub fn Muted(&self) -> bool { + fn Muted(&self) -> bool { false } - pub fn SetMuted(&mut self, _muted: bool) { + fn SetMuted(&mut self, _muted: bool) { } - pub fn DefaultMuted(&self) -> bool { + fn DefaultMuted(&self) -> bool { false } - pub fn SetDefaultMuted(&mut self, _default_muted: bool) -> ErrorResult { + fn SetDefaultMuted(&mut self, _default_muted: bool) -> ErrorResult { Ok(()) } } - diff --git a/src/components/script/dom/htmlmetaelement.rs b/src/components/script/dom/htmlmetaelement.rs index 3ecba0013d2..03cac21fca7 100644 --- a/src/components/script/dom/htmlmetaelement.rs +++ b/src/components/script/dom/htmlmetaelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLMetaElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMetaElementTypeId; @@ -28,48 +28,59 @@ impl HTMLMetaElementDerived for EventTarget { } impl HTMLMetaElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMetaElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLMetaElement { HTMLMetaElement { htmlelement: HTMLElement::new_inherited(HTMLMetaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMetaElement> { - let element = HTMLMetaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLMetaElement> { + let element = HTMLMetaElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLMetaElementBinding::Wrap) } } -impl HTMLMetaElement { - pub fn Name(&self) -> DOMString { +pub trait HTMLMetaElementMethods { + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn HttpEquiv(&self) -> DOMString; + fn SetHttpEquiv(&mut self, _http_equiv: DOMString) -> ErrorResult; + fn Content(&self) -> DOMString; + fn SetContent(&mut self, _content: DOMString) -> ErrorResult; + fn Scheme(&self) -> DOMString; + fn SetScheme(&mut self, _scheme: DOMString) -> ErrorResult; +} + +impl<'a> HTMLMetaElementMethods for JSRef<'a, HTMLMetaElement> { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn HttpEquiv(&self) -> DOMString { + fn HttpEquiv(&self) -> DOMString { ~"" } - pub fn SetHttpEquiv(&mut self, _http_equiv: DOMString) -> ErrorResult { + fn SetHttpEquiv(&mut self, _http_equiv: DOMString) -> ErrorResult { Ok(()) } - pub fn Content(&self) -> DOMString { + fn Content(&self) -> DOMString { ~"" } - pub fn SetContent(&mut self, _content: DOMString) -> ErrorResult { + fn SetContent(&mut self, _content: DOMString) -> ErrorResult { Ok(()) } - pub fn Scheme(&self) -> DOMString { + fn Scheme(&self) -> DOMString { ~"" } - pub fn SetScheme(&mut self, _scheme: DOMString) -> ErrorResult { + fn SetScheme(&mut self, _scheme: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlmeterelement.rs b/src/components/script/dom/htmlmeterelement.rs index 044c4785cb8..d16a82b79da 100644 --- a/src/components/script/dom/htmlmeterelement.rs +++ b/src/components/script/dom/htmlmeterelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLMeterElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMeterElementTypeId; @@ -28,64 +28,80 @@ impl HTMLMeterElementDerived for EventTarget { } impl HTMLMeterElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMeterElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLMeterElement { HTMLMeterElement { htmlelement: HTMLElement::new_inherited(HTMLMeterElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMeterElement> { - let element = HTMLMeterElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLMeterElement> { + let element = HTMLMeterElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLMeterElementBinding::Wrap) } } -impl HTMLMeterElement { - pub fn Value(&self) -> f64 { +pub trait HTMLMeterElementMethods { + fn Value(&self) -> f64; + fn SetValue(&mut self, _value: f64) -> ErrorResult; + fn Min(&self) -> f64; + fn SetMin(&mut self, _min: f64) -> ErrorResult; + fn Max(&self) -> f64; + fn SetMax(&mut self, _max: f64) -> ErrorResult; + fn Low(&self) -> f64; + fn SetLow(&mut self, _low: f64) -> ErrorResult; + fn High(&self) -> f64; + fn SetHigh(&mut self, _high: f64) -> ErrorResult; + fn Optimum(&self) -> f64; + fn SetOptimum(&mut self, _optimum: f64) -> ErrorResult; +} + +impl<'a> HTMLMeterElementMethods for JSRef<'a, HTMLMeterElement> { + fn Value(&self) -> f64 { 0.0 } - pub fn SetValue(&mut self, _value: f64) -> ErrorResult { + fn SetValue(&mut self, _value: f64) -> ErrorResult { Ok(()) } - pub fn Min(&self) -> f64 { + fn Min(&self) -> f64 { 0.0 } - pub fn SetMin(&mut self, _min: f64) -> ErrorResult { + fn SetMin(&mut self, _min: f64) -> ErrorResult { Ok(()) } - pub fn Max(&self) -> f64 { + fn Max(&self) -> f64 { 0.0 } - pub fn SetMax(&mut self, _max: f64) -> ErrorResult { + fn SetMax(&mut self, _max: f64) -> ErrorResult { Ok(()) } - pub fn Low(&self) -> f64 { + fn Low(&self) -> f64 { 0.0 } - pub fn SetLow(&mut self, _low: f64) -> ErrorResult { + fn SetLow(&mut self, _low: f64) -> ErrorResult { Ok(()) } - pub fn High(&self) -> f64 { + fn High(&self) -> f64 { 0.0 } - pub fn SetHigh(&mut self, _high: f64) -> ErrorResult { + fn SetHigh(&mut self, _high: f64) -> ErrorResult { Ok(()) } - pub fn Optimum(&self) -> f64 { + fn Optimum(&self) -> f64 { 0.0 } - pub fn SetOptimum(&mut self, _optimum: f64) -> ErrorResult { + fn SetOptimum(&mut self, _optimum: f64) -> ErrorResult { Ok(()) } } + diff --git a/src/components/script/dom/htmlmodelement.rs b/src/components/script/dom/htmlmodelement.rs index a656b891b1b..c28eb9cdfba 100644 --- a/src/components/script/dom/htmlmodelement.rs +++ b/src/components/script/dom/htmlmodelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLModElementBinding; use dom::bindings::codegen::InheritTypes::HTMLModElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLModElementTypeId; @@ -28,32 +28,39 @@ impl HTMLModElementDerived for EventTarget { } impl HTMLModElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLModElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLModElement { HTMLModElement { htmlelement: HTMLElement::new_inherited(HTMLModElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLModElement> { - let element = HTMLModElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLModElement> { + let element = HTMLModElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLModElementBinding::Wrap) } } -impl HTMLModElement { - pub fn Cite(&self) -> DOMString { +pub trait HTMLModElementMethods { + fn Cite(&self) -> DOMString; + fn SetCite(&mut self, _cite: DOMString) -> ErrorResult; + fn DateTime(&self) -> DOMString; + fn SetDateTime(&mut self, _datetime: DOMString) -> ErrorResult; +} + +impl<'a> HTMLModElementMethods for JSRef<'a, HTMLModElement> { + fn Cite(&self) -> DOMString { ~"" } - pub fn SetCite(&mut self, _cite: DOMString) -> ErrorResult { + fn SetCite(&mut self, _cite: DOMString) -> ErrorResult { Ok(()) } - pub fn DateTime(&self) -> DOMString { + fn DateTime(&self) -> DOMString { ~"" } - pub fn SetDateTime(&mut self, _datetime: DOMString) -> ErrorResult { + fn SetDateTime(&mut self, _datetime: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlobjectelement.rs b/src/components/script/dom/htmlobjectelement.rs index e2c7d16c03d..c020765d431 100644 --- a/src/components/script/dom/htmlobjectelement.rs +++ b/src/components/script/dom/htmlobjectelement.rs @@ -2,10 +2,11 @@ * 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::AttrMethods; use dom::bindings::codegen::BindingDeclarations::HTMLObjectElementBinding; use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLObjectElementTypeId}; @@ -41,14 +42,14 @@ impl HTMLObjectElementDerived for EventTarget { } impl HTMLObjectElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLObjectElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLObjectElement { HTMLObjectElement { htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document), } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLObjectElement> { - let element = HTMLObjectElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLObjectElement> { + let element = HTMLObjectElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLObjectElementBinding::Wrap) } } @@ -57,15 +58,15 @@ trait ProcessDataURL { fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>); } -impl ProcessDataURL for JS<HTMLObjectElement> { +impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> { // Makes the local `data` member match the status of the `data` attribute and starts /// prefetching the image. This method must be called after `data` is changed. fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>) { - let elem: JS<Element> = ElementCast::from(self); + let elem: &JSRef<Element> = ElementCast::from_ref(self); // TODO: support other values - match (elem.get_attribute(Null, "type").map(|x| x.get().Value()), - elem.get_attribute(Null, "data").map(|x| x.get().Value())) { + match (elem.get_attribute(Null, "type").map(|x| x.root().Value()), + elem.get_attribute(Null, "data").map(|x| x.root().Value())) { (None, Some(uri)) => { if is_image_data(uri) { let data_url = parse_url(uri, url); @@ -78,177 +79,220 @@ impl ProcessDataURL for JS<HTMLObjectElement> { } } -impl HTMLObjectElement { - pub fn Data(&self) -> DOMString { +pub trait HTMLObjectElementMethods { + fn Data(&self) -> DOMString; + fn SetData(&mut self, _data: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn UseMap(&self) -> DOMString; + fn SetUseMap(&mut self, _use_map: DOMString) -> ErrorResult; + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; + fn Height(&self) -> DOMString; + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult; + fn GetContentDocument(&self) -> Option<Temporary<Document>>; + fn GetContentWindow(&self) -> Option<Temporary<Window>>; + fn WillValidate(&self) -> bool; + fn Validity(&self) -> Temporary<ValidityState>; + fn ValidationMessage(&self) -> DOMString; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&mut self, _error: DOMString); + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Archive(&self) -> DOMString; + fn SetArchive(&mut self, _archive: DOMString) -> ErrorResult; + fn Code(&self) -> DOMString; + fn SetCode(&mut self, _code: DOMString) -> ErrorResult; + fn Declare(&self) -> bool; + fn SetDeclare(&mut self, _declare: bool) -> ErrorResult; + fn Hspace(&self) -> u32; + fn SetHspace(&mut self, _hspace: u32) -> ErrorResult; + fn Standby(&self) -> DOMString; + fn SetStandby(&mut self, _standby: DOMString) -> ErrorResult; + fn Vspace(&self) -> u32; + fn SetVspace(&mut self, _vspace: u32) -> ErrorResult; + fn CodeBase(&self) -> DOMString; + fn SetCodeBase(&mut self, _codebase: DOMString) -> ErrorResult; + fn CodeType(&self) -> DOMString; + fn SetCodeType(&mut self, _codetype: DOMString) -> ErrorResult; + fn Border(&self) -> DOMString; + fn SetBorder(&mut self, _border: DOMString) -> ErrorResult; + fn GetSVGDocument(&self) -> Option<Temporary<Document>>; +} + +impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> { + fn Data(&self) -> DOMString { ~"" } - pub fn SetData(&mut self, _data: DOMString) -> ErrorResult { + fn SetData(&mut self, _data: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn UseMap(&self) -> DOMString { + fn UseMap(&self) -> DOMString { ~"" } - pub fn SetUseMap(&mut self, _use_map: DOMString) -> ErrorResult { + fn SetUseMap(&mut self, _use_map: DOMString) -> ErrorResult { Ok(()) } - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> DOMString { + fn Height(&self) -> DOMString { ~"" } - pub fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { + fn SetHeight(&mut self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn GetContentDocument(&self) -> Option<JS<Document>> { + fn GetContentDocument(&self) -> Option<Temporary<Document>> { None } - pub fn GetContentWindow(&self) -> Option<JS<Window>> { + fn GetContentWindow(&self) -> Option<Temporary<Window>> { None } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn Validity(&self) -> JS<ValidityState> { - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - ValidityState::new(&doc.window) + fn Validity(&self) -> Temporary<ValidityState> { + let window = window_from_node(self).root(); + ValidityState::new(&*window) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { false } - pub fn SetCustomValidity(&mut self, _error: DOMString) { + fn SetCustomValidity(&mut self, _error: DOMString) { } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Archive(&self) -> DOMString { + fn Archive(&self) -> DOMString { ~"" } - pub fn SetArchive(&mut self, _archive: DOMString) -> ErrorResult { + fn SetArchive(&mut self, _archive: DOMString) -> ErrorResult { Ok(()) } - pub fn Code(&self) -> DOMString { + fn Code(&self) -> DOMString { ~"" } - pub fn SetCode(&mut self, _code: DOMString) -> ErrorResult { + fn SetCode(&mut self, _code: DOMString) -> ErrorResult { Ok(()) } - pub fn Declare(&self) -> bool { + fn Declare(&self) -> bool { false } - pub fn SetDeclare(&mut self, _declare: bool) -> ErrorResult { + fn SetDeclare(&mut self, _declare: bool) -> ErrorResult { Ok(()) } - pub fn Hspace(&self) -> u32 { + fn Hspace(&self) -> u32 { 0 } - pub fn SetHspace(&mut self, _hspace: u32) -> ErrorResult { + fn SetHspace(&mut self, _hspace: u32) -> ErrorResult { Ok(()) } - pub fn Standby(&self) -> DOMString { + fn Standby(&self) -> DOMString { ~"" } - pub fn SetStandby(&mut self, _standby: DOMString) -> ErrorResult { + fn SetStandby(&mut self, _standby: DOMString) -> ErrorResult { Ok(()) } - pub fn Vspace(&self) -> u32 { + fn Vspace(&self) -> u32 { 0 } - pub fn SetVspace(&mut self, _vspace: u32) -> ErrorResult { + fn SetVspace(&mut self, _vspace: u32) -> ErrorResult { Ok(()) } - pub fn CodeBase(&self) -> DOMString { + fn CodeBase(&self) -> DOMString { ~"" } - pub fn SetCodeBase(&mut self, _codebase: DOMString) -> ErrorResult { + fn SetCodeBase(&mut self, _codebase: DOMString) -> ErrorResult { Ok(()) } - pub fn CodeType(&self) -> DOMString { + fn CodeType(&self) -> DOMString { ~"" } - pub fn SetCodeType(&mut self, _codetype: DOMString) -> ErrorResult { + fn SetCodeType(&mut self, _codetype: DOMString) -> ErrorResult { Ok(()) } - pub fn Border(&self) -> DOMString { + fn Border(&self) -> DOMString { ~"" } - pub fn SetBorder(&mut self, _border: DOMString) -> ErrorResult { + fn SetBorder(&mut self, _border: DOMString) -> ErrorResult { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<JS<Document>> { + fn GetSVGDocument(&self) -> Option<Temporary<Document>> { None } } -impl VirtualMethods for JS<HTMLObjectElement> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self); - Some(~htmlelement as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self); + Some(htmlelement as &mut VirtualMethods:) } fn after_set_attr(&mut self, name: DOMString, value: DOMString) { @@ -258,9 +302,9 @@ impl VirtualMethods for JS<HTMLObjectElement> { } if "data" == name { - let window = window_from_node(self); - let url = Some(window.get().get_url()); - self.process_data_url(window.get().image_cache_task.clone(), url); + let window = window_from_node(self).root(); + let url = Some(window.deref().get_url()); + self.process_data_url(window.deref().image_cache_task.clone(), url); } } } diff --git a/src/components/script/dom/htmlolistelement.rs b/src/components/script/dom/htmlolistelement.rs index ced7b98edb4..b8694f356c8 100644 --- a/src/components/script/dom/htmlolistelement.rs +++ b/src/components/script/dom/htmlolistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLOListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOListElementTypeId; @@ -28,48 +28,59 @@ impl HTMLOListElementDerived for EventTarget { } impl HTMLOListElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOListElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOListElement { HTMLOListElement { htmlelement: HTMLElement::new_inherited(HTMLOListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOListElement> { - let element = HTMLOListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOListElement> { + let element = HTMLOListElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLOListElementBinding::Wrap) } } -impl HTMLOListElement { - pub fn Reversed(&self) -> bool { +pub trait HTMLOListElementMethods { + fn Reversed(&self) -> bool; + fn SetReversed(&self, _reversed: bool) -> ErrorResult; + fn Start(&self) -> i32; + fn SetStart(&mut self, _start: i32) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Compact(&self) -> bool; + fn SetCompact(&self, _compact: bool) -> ErrorResult; +} + +impl<'a> HTMLOListElementMethods for JSRef<'a, HTMLOListElement> { + fn Reversed(&self) -> bool { false } - pub fn SetReversed(&self, _reversed: bool) -> ErrorResult { + fn SetReversed(&self, _reversed: bool) -> ErrorResult { Ok(()) } - pub fn Start(&self) -> i32 { + fn Start(&self) -> i32 { 0 } - pub fn SetStart(&mut self, _start: i32) -> ErrorResult { + fn SetStart(&mut self, _start: i32) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Compact(&self) -> bool { + fn Compact(&self) -> bool { false } - pub fn SetCompact(&self, _compact: bool) -> ErrorResult { + fn SetCompact(&self, _compact: bool) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmloptgroupelement.rs b/src/components/script/dom/htmloptgroupelement.rs index dfddb3e2546..3b5c5fab456 100644 --- a/src/components/script/dom/htmloptgroupelement.rs +++ b/src/components/script/dom/htmloptgroupelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLOptGroupElementBinding; use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOptGroupElementTypeId; @@ -28,32 +28,39 @@ impl HTMLOptGroupElementDerived for EventTarget { } impl HTMLOptGroupElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOptGroupElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOptGroupElement { HTMLOptGroupElement { htmlelement: HTMLElement::new_inherited(HTMLOptGroupElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptGroupElement> { - let element = HTMLOptGroupElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOptGroupElement> { + let element = HTMLOptGroupElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLOptGroupElementBinding::Wrap) } } -impl HTMLOptGroupElement { - pub fn Disabled(&self) -> bool { +pub trait HTMLOptGroupElementMethods { + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn Label(&self) -> DOMString; + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult; +} + +impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn Label(&self) -> DOMString { + fn Label(&self) -> DOMString { ~"" } - pub fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmloptionelement.rs b/src/components/script/dom/htmloptionelement.rs index e6a030df48c..550d352af36 100644 --- a/src/components/script/dom/htmloptionelement.rs +++ b/src/components/script/dom/htmloptionelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLOptionElementBinding; use dom::bindings::codegen::InheritTypes::HTMLOptionElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOptionElementTypeId; @@ -29,72 +29,89 @@ impl HTMLOptionElementDerived for EventTarget { } impl HTMLOptionElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOptionElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOptionElement { HTMLOptionElement { htmlelement: HTMLElement::new_inherited(HTMLOptionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptionElement> { - let element = HTMLOptionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOptionElement> { + let element = HTMLOptionElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLOptionElementBinding::Wrap) } } -impl HTMLOptionElement { - pub fn Disabled(&self) -> bool { +pub trait HTMLOptionElementMethods { + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn Label(&self) -> DOMString; + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult; + fn DefaultSelected(&self) -> bool; + fn SetDefaultSelected(&mut self, _default_selected: bool) -> ErrorResult; + fn Selected(&self) -> bool; + fn SetSelected(&mut self, _selected: bool) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; + fn Text(&self) -> DOMString; + fn SetText(&mut self, _text: DOMString) -> ErrorResult; + fn Index(&self) -> i32; +} + +impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn Label(&self) -> DOMString { + fn Label(&self) -> DOMString { ~"" } - pub fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { Ok(()) } - pub fn DefaultSelected(&self) -> bool { + fn DefaultSelected(&self) -> bool { false } - pub fn SetDefaultSelected(&mut self, _default_selected: bool) -> ErrorResult { + fn SetDefaultSelected(&mut self, _default_selected: bool) -> ErrorResult { Ok(()) } - pub fn Selected(&self) -> bool { + fn Selected(&self) -> bool { false } - pub fn SetSelected(&mut self, _selected: bool) -> ErrorResult { + fn SetSelected(&mut self, _selected: bool) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn Text(&self) -> DOMString { + fn Text(&self) -> DOMString { ~"" } - pub fn SetText(&mut self, _text: DOMString) -> ErrorResult { + fn SetText(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } - pub fn Index(&self) -> i32 { + fn Index(&self) -> i32 { 0 } } diff --git a/src/components/script/dom/htmloutputelement.rs b/src/components/script/dom/htmloutputelement.rs index 1a1ec088489..3952f3cef97 100644 --- a/src/components/script/dom/htmloutputelement.rs +++ b/src/components/script/dom/htmloutputelement.rs @@ -4,14 +4,14 @@ use dom::bindings::codegen::BindingDeclarations::HTMLOutputElementBinding; use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOutputElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::HTMLFormElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; use dom::validitystate::ValidityState; use servo_util::str::DOMString; @@ -30,79 +30,93 @@ impl HTMLOutputElementDerived for EventTarget { } impl HTMLOutputElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOutputElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOutputElement { HTMLOutputElement { htmlelement: HTMLElement::new_inherited(HTMLOutputElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOutputElement> { - let element = HTMLOutputElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOutputElement> { + let element = HTMLOutputElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLOutputElementBinding::Wrap) } } -impl HTMLOutputElement { - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { +pub trait HTMLOutputElementMethods { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn DefaultValue(&self) -> DOMString; + fn SetDefaultValue(&mut self, _value: DOMString) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; + fn WillValidate(&self) -> bool; + fn SetWillValidate(&mut self, _will_validate: bool); + fn Validity(&self) -> Temporary<ValidityState>; + fn ValidationMessage(&self) -> DOMString; + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&mut self, _error: DOMString); +} + +impl<'a> HTMLOutputElementMethods for JSRef<'a, HTMLOutputElement> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn DefaultValue(&self) -> DOMString { + fn DefaultValue(&self) -> DOMString { ~"" } - pub fn SetDefaultValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetDefaultValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn SetWillValidate(&mut self, _will_validate: bool) { - } - - pub fn Validity(&self) -> JS<ValidityState> { - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - ValidityState::new(&doc.window) + fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { + fn Validity(&self) -> Temporary<ValidityState> { + let window = window_from_node(self).root(); + ValidityState::new(&*window) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { Ok(()) } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { true } - pub fn SetCustomValidity(&mut self, _error: DOMString) { + fn SetCustomValidity(&mut self, _error: DOMString) { } } diff --git a/src/components/script/dom/htmlparagraphelement.rs b/src/components/script/dom/htmlparagraphelement.rs index e6e6473e816..95620dec3dd 100644 --- a/src/components/script/dom/htmlparagraphelement.rs +++ b/src/components/script/dom/htmlparagraphelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLParagraphElementBinding; use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLParagraphElementTypeId; @@ -28,24 +28,29 @@ impl HTMLParagraphElementDerived for EventTarget { } impl HTMLParagraphElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLParagraphElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLParagraphElement { HTMLParagraphElement { htmlelement: HTMLElement::new_inherited(HTMLParagraphElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParagraphElement> { - let element = HTMLParagraphElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLParagraphElement> { + let element = HTMLParagraphElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLParagraphElementBinding::Wrap) } } -impl HTMLParagraphElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLParagraphElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLParagraphElementMethods for JSRef<'a, HTMLParagraphElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlparamelement.rs b/src/components/script/dom/htmlparamelement.rs index 781221bfad0..115d1759964 100644 --- a/src/components/script/dom/htmlparamelement.rs +++ b/src/components/script/dom/htmlparamelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLParamElementBinding; use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLParamElementTypeId; @@ -28,48 +28,59 @@ impl HTMLParamElementDerived for EventTarget { } impl HTMLParamElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLParamElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLParamElement { HTMLParamElement { htmlelement: HTMLElement::new_inherited(HTMLParamElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParamElement> { - let element = HTMLParamElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLParamElement> { + let element = HTMLParamElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLParamElementBinding::Wrap) } } -impl HTMLParamElement { - pub fn Name(&self) -> DOMString { +pub trait HTMLParamElementMethods { + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn ValueType(&self) -> DOMString; + fn SetValueType(&mut self, _value_type: DOMString) -> ErrorResult; +} + +impl<'a> HTMLParamElementMethods for JSRef<'a, HTMLParamElement> { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) -> ErrorResult { + fn SetValue(&mut self, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn ValueType(&self) -> DOMString { + fn ValueType(&self) -> DOMString { ~"" } - pub fn SetValueType(&mut self, _value_type: DOMString) -> ErrorResult { + fn SetValueType(&mut self, _value_type: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlpreelement.rs b/src/components/script/dom/htmlpreelement.rs index 9b3e2c73953..1cbb5236383 100644 --- a/src/components/script/dom/htmlpreelement.rs +++ b/src/components/script/dom/htmlpreelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLPreElementBinding; use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLPreElementTypeId; @@ -28,24 +28,29 @@ impl HTMLPreElementDerived for EventTarget { } impl HTMLPreElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLPreElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLPreElement { HTMLPreElement { htmlelement: HTMLElement::new_inherited(HTMLPreElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLPreElement> { - let element = HTMLPreElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLPreElement> { + let element = HTMLPreElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLPreElementBinding::Wrap) } } -impl HTMLPreElement { - pub fn Width(&self) -> i32 { +pub trait HTMLPreElementMethods { + fn Width(&self) -> i32; + fn SetWidth(&mut self, _width: i32) -> ErrorResult; +} + +impl<'a> HTMLPreElementMethods for JSRef<'a, HTMLPreElement> { + fn Width(&self) -> i32 { 0 } - pub fn SetWidth(&mut self, _width: i32) -> ErrorResult { + fn SetWidth(&mut self, _width: i32) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlprogresselement.rs b/src/components/script/dom/htmlprogresselement.rs index ccd0463539f..d1470c29cbf 100644 --- a/src/components/script/dom/htmlprogresselement.rs +++ b/src/components/script/dom/htmlprogresselement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLProgressElementBinding; use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLProgressElementTypeId; @@ -28,40 +28,49 @@ impl HTMLProgressElementDerived for EventTarget { } impl HTMLProgressElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLProgressElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLProgressElement { HTMLProgressElement { htmlelement: HTMLElement::new_inherited(HTMLProgressElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLProgressElement> { - let element = HTMLProgressElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLProgressElement> { + let element = HTMLProgressElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLProgressElementBinding::Wrap) } } -impl HTMLProgressElement { - pub fn Value(&self) -> f64 { +pub trait HTMLProgressElementMethods { + fn Value(&self) -> f64; + fn SetValue(&mut self, _value: f64) -> ErrorResult; + fn Max(&self) -> f64; + fn SetMax(&mut self, _max: f64) -> ErrorResult; + fn Position(&self) -> f64; + fn GetPositiom(&self) -> Fallible<f64>; +} + +impl<'a> HTMLProgressElementMethods for JSRef<'a, HTMLProgressElement> { + fn Value(&self) -> f64 { 0f64 } - pub fn SetValue(&mut self, _value: f64) -> ErrorResult { + fn SetValue(&mut self, _value: f64) -> ErrorResult { Ok(()) } - pub fn Max(&self) -> f64 { + fn Max(&self) -> f64 { 0f64 } - pub fn SetMax(&mut self, _max: f64) -> ErrorResult { + fn SetMax(&mut self, _max: f64) -> ErrorResult { Ok(()) } - pub fn Position(&self) -> f64 { + fn Position(&self) -> f64 { 0f64 } - pub fn GetPositiom(&self) -> Fallible<f64> { + fn GetPositiom(&self) -> Fallible<f64> { Ok(0f64) } } diff --git a/src/components/script/dom/htmlquoteelement.rs b/src/components/script/dom/htmlquoteelement.rs index 87e313cc857..11aba48adfe 100644 --- a/src/components/script/dom/htmlquoteelement.rs +++ b/src/components/script/dom/htmlquoteelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLQuoteElementBinding; use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLQuoteElementTypeId; @@ -28,24 +28,29 @@ impl HTMLQuoteElementDerived for EventTarget { } impl HTMLQuoteElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLQuoteElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLQuoteElement { HTMLQuoteElement { htmlelement: HTMLElement::new_inherited(HTMLQuoteElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLQuoteElement> { - let element = HTMLQuoteElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLQuoteElement> { + let element = HTMLQuoteElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLQuoteElementBinding::Wrap) } } -impl HTMLQuoteElement { - pub fn Cite(&self) -> DOMString { +pub trait HTMLQuoteElementMethods { + fn Cite(&self) -> DOMString; + fn SetCite(&self, _cite: DOMString) -> ErrorResult; +} + +impl<'a> HTMLQuoteElementMethods for JSRef<'a, HTMLQuoteElement> { + fn Cite(&self) -> DOMString { ~"" } - pub fn SetCite(&self, _cite: DOMString) -> ErrorResult { + fn SetCite(&self, _cite: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlscriptelement.rs b/src/components/script/dom/htmlscriptelement.rs index bccaa740906..79b42ddc423 100644 --- a/src/components/script/dom/htmlscriptelement.rs +++ b/src/components/script/dom/htmlscriptelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLScriptElementBinding; use dom::bindings::codegen::InheritTypes::HTMLScriptElementDerived; use dom::bindings::codegen::InheritTypes::ElementCast; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{HTMLScriptElementTypeId, Element, AttributeHandlers}; @@ -29,89 +29,110 @@ impl HTMLScriptElementDerived for EventTarget { } impl HTMLScriptElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLScriptElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLScriptElement { HTMLScriptElement { htmlelement: HTMLElement::new_inherited(HTMLScriptElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLScriptElement> { - let element = HTMLScriptElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLScriptElement> { + let element = HTMLScriptElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLScriptElementBinding::Wrap) } } -impl HTMLScriptElement { - pub fn Src(&self, abstract_self: &JS<HTMLScriptElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); +pub trait HTMLScriptElementMethods { + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Charset(&self) -> DOMString; + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult; + fn Async(&self) -> bool; + fn SetAsync(&self, _async: bool) -> ErrorResult; + fn Defer(&self) -> bool; + fn SetDefer(&self, _defer: bool) -> ErrorResult; + fn CrossOrigin(&self) -> DOMString; + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult; + fn Text(&self) -> DOMString; + fn SetText(&mut self, _text: DOMString) -> ErrorResult; + fn Event(&self) -> DOMString; + fn SetEvent(&mut self, _event: DOMString) -> ErrorResult; + fn HtmlFor(&self) -> DOMString; + fn SetHtmlFor(&mut self, _html_for: DOMString) -> ErrorResult; +} + +impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> { + fn Src(&self) -> DOMString { + let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_url_attribute("src") } - pub fn SetSrc(&mut self, _abstract_self: &JS<HTMLScriptElement>, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Charset(&self) -> DOMString { + fn Charset(&self) -> DOMString { ~"" } - pub fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { + fn SetCharset(&mut self, _charset: DOMString) -> ErrorResult { Ok(()) } - pub fn Async(&self) -> bool { + fn Async(&self) -> bool { false } - pub fn SetAsync(&self, _async: bool) -> ErrorResult { + fn SetAsync(&self, _async: bool) -> ErrorResult { Ok(()) } - pub fn Defer(&self) -> bool { + fn Defer(&self) -> bool { false } - pub fn SetDefer(&self, _defer: bool) -> ErrorResult { + fn SetDefer(&self, _defer: bool) -> ErrorResult { Ok(()) } - pub fn CrossOrigin(&self) -> DOMString { + fn CrossOrigin(&self) -> DOMString { ~"" } - pub fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { + fn SetCrossOrigin(&mut self, _cross_origin: DOMString) -> ErrorResult { Ok(()) } - pub fn Text(&self) -> DOMString { + fn Text(&self) -> DOMString { ~"" } - pub fn SetText(&mut self, _text: DOMString) -> ErrorResult { + fn SetText(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } - pub fn Event(&self) -> DOMString { + fn Event(&self) -> DOMString { ~"" } - pub fn SetEvent(&mut self, _event: DOMString) -> ErrorResult { + fn SetEvent(&mut self, _event: DOMString) -> ErrorResult { Ok(()) } - pub fn HtmlFor(&self) -> DOMString { + fn HtmlFor(&self) -> DOMString { ~"" } - pub fn SetHtmlFor(&mut self, _html_for: DOMString) -> ErrorResult { + fn SetHtmlFor(&mut self, _html_for: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlselectelement.rs b/src/components/script/dom/htmlselectelement.rs index 47353bd8eb5..cabeacbf47a 100644 --- a/src/components/script/dom/htmlselectelement.rs +++ b/src/components/script/dom/htmlselectelement.rs @@ -5,14 +5,14 @@ use dom::bindings::codegen::BindingDeclarations::HTMLSelectElementBinding; use dom::bindings::codegen::InheritTypes::HTMLSelectElementDerived; use dom::bindings::codegen::UnionTypes::{HTMLElementOrLong, HTMLOptionElementOrHTMLOptGroupElement}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLSelectElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::HTMLFormElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; use dom::htmloptionelement::HTMLOptionElement; use dom::validitystate::ValidityState; use servo_util::str::DOMString; @@ -32,152 +32,185 @@ impl HTMLSelectElementDerived for EventTarget { } impl HTMLSelectElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSelectElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLSelectElement { HTMLSelectElement { htmlelement: HTMLElement::new_inherited(HTMLSelectElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSelectElement> { - let element = HTMLSelectElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLSelectElement> { + let element = HTMLSelectElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLSelectElementBinding::Wrap) } } -impl HTMLSelectElement { - pub fn Autofocus(&self) -> bool { +pub trait HTMLSelectElementMethods { + fn Autofocus(&self) -> bool; + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult; + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>; + fn Multiple(&self) -> bool; + fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Required(&self) -> bool; + fn SetRequired(&mut self, _multiple: bool) -> ErrorResult; + fn Size(&self) -> u32; + fn SetSize(&mut self, _size: u32) -> ErrorResult; + fn Type(&self) -> DOMString; + fn Length(&self) -> u32; + fn SetLength(&mut self, _length: u32) -> ErrorResult; + fn Item(&self, _index: u32) -> Option<Temporary<Element>>; + fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>>; + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>>; + fn IndexedSetter(&mut self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult; + fn Remove_(&self); + fn Remove(&self, _index: i32); + fn SelectedIndex(&self) -> i32; + fn SetSelectedIndex(&mut self, _index: i32) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString); + fn WillValidate(&self) -> bool; + fn SetWillValidate(&mut self, _will_validate: bool); + fn Validity(&self) -> Temporary<ValidityState>; + fn ValidationMessage(&self) -> DOMString; + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&mut self, _error: DOMString); + fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult; +} + +impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> { + fn Autofocus(&self) -> bool { false } - pub fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { Ok(()) } - pub fn Disabled(&self) -> bool { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { + fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> { None } - pub fn Multiple(&self) -> bool { + fn Multiple(&self) -> bool { false } - pub fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult { + fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Required(&self) -> bool { + fn Required(&self) -> bool { false } - pub fn SetRequired(&mut self, _multiple: bool) -> ErrorResult { + fn SetRequired(&mut self, _multiple: bool) -> ErrorResult { Ok(()) } - pub fn Size(&self) -> u32 { + fn Size(&self) -> u32 { 0 } - pub fn SetSize(&mut self, _size: u32) -> ErrorResult { + fn SetSize(&mut self, _size: u32) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn Length(&self) -> u32 { + fn Length(&self) -> u32 { 0 } - pub fn SetLength(&mut self, _length: u32) -> ErrorResult { + fn SetLength(&mut self, _length: u32) -> ErrorResult { Ok(()) } - pub fn Item(&self, _index: u32) -> Option<JS<Element>> { + fn Item(&self, _index: u32) -> Option<Temporary<Element>> { None } - pub fn NamedItem(&self, _name: DOMString) -> Option<JS<HTMLOptionElement>> { + fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>> { None } - pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<JS<Element>> { + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>> { None } - pub fn IndexedSetter(&mut self, _index: u32, _option: Option<JS<HTMLOptionElement>>) -> ErrorResult { + fn IndexedSetter(&mut self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult { Ok(()) } - pub fn Remove_(&self) { + fn Remove_(&self) { } - pub fn Remove(&self, _index: i32) { + fn Remove(&self, _index: i32) { } - pub fn SelectedIndex(&self) -> i32 { + fn SelectedIndex(&self) -> i32 { 0 } - pub fn SetSelectedIndex(&mut self, _index: i32) -> ErrorResult { + fn SetSelectedIndex(&mut self, _index: i32) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) { + fn SetValue(&mut self, _value: DOMString) { } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn SetWillValidate(&mut self, _will_validate: bool) { - } - - pub fn Validity(&self) -> JS<ValidityState> { - let doc = self.htmlelement.element.node.owner_doc(); - let doc = doc.get(); - ValidityState::new(&doc.window) + fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { + fn Validity(&self) -> Temporary<ValidityState> { + let window = window_from_node(self).root(); + ValidityState::new(&*window) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { + fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult { Ok(()) } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { true } - pub fn SetCustomValidity(&mut self, _error: DOMString) { + fn SetCustomValidity(&mut self, _error: DOMString) { } - pub fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult { + fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs index 8bd5beb6cf8..3a2148547ee 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -4,15 +4,15 @@ use servo_util::namespace; use dom::attr::Attr; -use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast}; use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; -use dom::bindings::js::JS; +use dom::bindings::js::JSRef; use dom::characterdata::CharacterData; use dom::comment::Comment; use dom::documenttype::DocumentType; use dom::element::Element; -use dom::node::NodeIterator; +use dom::node::{Node, NodeIterator}; use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId}; use dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId}; use dom::node::{TextNodeTypeId, NodeHelpers}; @@ -30,24 +30,25 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { html.push_str( match node.type_id() { ElementNodeTypeId(..) => { - let elem: JS<Element> = ElementCast::to(&node).unwrap(); - serialize_elem(&elem, &mut open_elements) + let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap(); + serialize_elem(elem, &mut open_elements) } CommentNodeTypeId => { - let comment: JS<Comment> = CommentCast::to(&node).unwrap(); - serialize_comment(&comment) + let comment: &JSRef<Comment> = CommentCast::to_ref(&node).unwrap(); + serialize_comment(comment) } TextNodeTypeId => { - let text: JS<Text> = TextCast::to(&node).unwrap(); - serialize_text(&text) + let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap(); + serialize_text(text) } DoctypeNodeTypeId => { - let doctype: JS<DocumentType> = DocumentTypeCast::to(&node).unwrap(); - serialize_doctype(&doctype) + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap(); + serialize_doctype(doctype) } ProcessingInstructionNodeTypeId => { - let processing_instruction: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node).unwrap(); - serialize_processing_instruction(&processing_instruction) + let processing_instruction: &JSRef<ProcessingInstruction> = + ProcessingInstructionCast::to_ref(&node).unwrap(); + serialize_processing_instruction(processing_instruction) } DocumentFragmentNodeTypeId => { ~"" @@ -64,47 +65,50 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { html } -fn serialize_comment(comment: &JS<Comment>) -> ~str { - ~"<!--" + comment.get().characterdata.data + "-->" +fn serialize_comment(comment: &JSRef<Comment>) -> ~str { + ~"<!--" + comment.deref().characterdata.data + "-->" } -fn serialize_text(text: &JS<Text>) -> ~str { - match text.get().characterdata.node.parent_node { +fn serialize_text(text: &JSRef<Text>) -> ~str { + let text_node: &JSRef<Node> = NodeCast::from_ref(text); + match text_node.parent_node().map(|node| node.root()) { Some(ref parent) if parent.is_element() => { - let elem: JS<Element> = ElementCast::to(parent).unwrap(); - match elem.get().local_name.as_slice() { + let elem: &JSRef<Element> = ElementCast::to_ref(&**parent).unwrap(); + match elem.deref().local_name.as_slice() { "style" | "script" | "xmp" | "iframe" | "noembed" | "noframes" | "plaintext" | - "noscript" if elem.get().namespace == namespace::HTML => { - text.get().characterdata.data.clone() + "noscript" if elem.deref().namespace == namespace::HTML => { + text.deref().characterdata.data.clone() }, - _ => escape(text.get().characterdata.data, false) + _ => escape(text.deref().characterdata.data, false) } } - _ => escape(text.get().characterdata.data, false) + _ => escape(text.deref().characterdata.data, false) } } -fn serialize_processing_instruction(processing_instruction: &JS<ProcessingInstruction>) -> ~str { - ~"<?" + processing_instruction.get().target + " " + processing_instruction.get().characterdata.data + "?>" +fn serialize_processing_instruction(processing_instruction: &JSRef<ProcessingInstruction>) -> ~str { + ~"<?" + processing_instruction.deref().target + " " + processing_instruction.deref().characterdata.data + "?>" } -fn serialize_doctype(doctype: &JS<DocumentType>) -> ~str { - ~"<!DOCTYPE" + doctype.get().name + ">" +fn serialize_doctype(doctype: &JSRef<DocumentType>) -> ~str { + ~"<!DOCTYPE" + doctype.deref().name + ">" } -fn serialize_elem(elem: &JS<Element>, open_elements: &mut Vec<~str>) -> ~str { - let mut rv = ~"<" + elem.get().local_name; - for attr in elem.get().attrs.iter() { - rv.push_str(serialize_attr(attr)); +fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str { + let mut rv = ~"<" + elem.deref().local_name; + for attr in elem.deref().attrs.iter() { + let attr = attr.root(); + rv.push_str(serialize_attr(&*attr)); }; rv.push_str(">"); - match elem.get().local_name.as_slice() { - "pre" | "listing" | "textarea" if elem.get().namespace == namespace::HTML => { - match elem.get().node.first_child { + match elem.deref().local_name.as_slice() { + "pre" | "listing" | "textarea" if elem.deref().namespace == namespace::HTML => { + let node: &JSRef<Node> = NodeCast::from_ref(elem); + match node.first_child().map(|child| child.root()) { Some(ref child) if child.is_text() => { - let text: JS<CharacterData> = CharacterDataCast::to(child).unwrap(); - if text.get().data.len() > 0 && text.get().data[0] == 0x0A as u8 { + let text: &JSRef<CharacterData> = CharacterDataCast::to_ref(&**child).unwrap(); + if text.deref().data.len() > 0 && text.deref().data[0] == 0x0A as u8 { rv.push_str("\x0A"); } }, @@ -113,26 +117,26 @@ fn serialize_elem(elem: &JS<Element>, open_elements: &mut Vec<~str>) -> ~str { }, _ => {} } - if !elem.get().is_void() { - open_elements.push(elem.get().local_name.clone()); + if !elem.deref().is_void() { + open_elements.push(elem.deref().local_name.clone()); } rv } -fn serialize_attr(attr: &JS<Attr>) -> ~str { - let attr_name = if attr.get().namespace == namespace::XML { - ~"xml:" + attr.get().local_name.clone() - } else if attr.get().namespace == namespace::XMLNS && - attr.get().local_name.as_slice() == "xmlns" { +fn serialize_attr(attr: &JSRef<Attr>) -> ~str { + let attr_name = if attr.deref().namespace == namespace::XML { + ~"xml:" + attr.deref().local_name.clone() + } else if attr.deref().namespace == namespace::XMLNS && + attr.deref().local_name.as_slice() == "xmlns" { ~"xmlns" - } else if attr.get().namespace == namespace::XMLNS { - ~"xmlns:" + attr.get().local_name.clone() - } else if attr.get().namespace == namespace::XLink { - ~"xlink:" + attr.get().local_name.clone() + } else if attr.deref().namespace == namespace::XMLNS { + ~"xmlns:" + attr.deref().local_name.clone() + } else if attr.deref().namespace == namespace::XLink { + ~"xlink:" + attr.deref().local_name.clone() } else { - attr.get().name.clone() + attr.deref().name.clone() }; - ~" " + attr_name + "=\"" + escape(attr.get().value, true) + "\"" + ~" " + attr_name + "=\"" + escape(attr.deref().value, true) + "\"" } fn escape(string: &str, attr_mode: bool) -> ~str { diff --git a/src/components/script/dom/htmlsourceelement.rs b/src/components/script/dom/htmlsourceelement.rs index 86f45c131ee..5ea79b01b45 100644 --- a/src/components/script/dom/htmlsourceelement.rs +++ b/src/components/script/dom/htmlsourceelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLSourceElementBinding; use dom::bindings::codegen::InheritTypes::HTMLSourceElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLSourceElementTypeId; @@ -28,40 +28,49 @@ impl HTMLSourceElementDerived for EventTarget { } impl HTMLSourceElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSourceElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLSourceElement { HTMLSourceElement { htmlelement: HTMLElement::new_inherited(HTMLSourceElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSourceElement> { - let element = HTMLSourceElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLSourceElement> { + let element = HTMLSourceElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLSourceElementBinding::Wrap) } } -impl HTMLSourceElement { - pub fn Src(&self) -> DOMString { +pub trait HTMLSourceElementMethods { + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Media(&self) -> DOMString; + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult; +} + +impl<'a> HTMLSourceElementMethods for JSRef<'a, HTMLSourceElement> { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Media(&self) -> DOMString { + fn Media(&self) -> DOMString { ~"" } - pub fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlspanelement.rs b/src/components/script/dom/htmlspanelement.rs index 14151f655a1..c4ccddeda33 100644 --- a/src/components/script/dom/htmlspanelement.rs +++ b/src/components/script/dom/htmlspanelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLSpanElementBinding; use dom::bindings::codegen::InheritTypes::HTMLSpanElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLSpanElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLSpanElementDerived for EventTarget { } impl HTMLSpanElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSpanElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLSpanElement { HTMLSpanElement { htmlelement: HTMLElement::new_inherited(HTMLSpanElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSpanElement> { - let element = HTMLSpanElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLSpanElement> { + let element = HTMLSpanElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLSpanElementBinding::Wrap) } } + +pub trait HTMLSpanElementMethods { +} diff --git a/src/components/script/dom/htmlstyleelement.rs b/src/components/script/dom/htmlstyleelement.rs index 29caa80da1d..b0688f30889 100644 --- a/src/components/script/dom/htmlstyleelement.rs +++ b/src/components/script/dom/htmlstyleelement.rs @@ -4,13 +4,13 @@ use dom::bindings::codegen::BindingDeclarations::HTMLStyleElementBinding; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLStyleElementDerived, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLStyleElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, ElementNodeTypeId, window_from_node}; +use dom::node::{Node, NodeMethods, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; use html::cssparse::parse_inline_css; use layout_interface::{AddStylesheetMsg, LayoutChan}; @@ -31,47 +31,58 @@ impl HTMLStyleElementDerived for EventTarget { } impl HTMLStyleElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLStyleElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLStyleElement { HTMLStyleElement { htmlelement: HTMLElement::new_inherited(HTMLStyleElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLStyleElement> { - let element = HTMLStyleElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLStyleElement> { + let element = HTMLStyleElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLStyleElementBinding::Wrap) } } -impl HTMLStyleElement { - pub fn Disabled(&self) -> bool { +pub trait HTMLStyleElementMethods { + fn Disabled(&self) -> bool; + fn SetDisabled(&self, _disabled: bool); + fn Media(&self) -> DOMString; + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; + fn Scoped(&self) -> bool; + fn SetScoped(&self, _scoped: bool) -> ErrorResult; +} + +impl<'a> HTMLStyleElementMethods for JSRef<'a, HTMLStyleElement> { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&self, _disabled: bool) { + fn SetDisabled(&self, _disabled: bool) { } - pub fn Media(&self) -> DOMString { + fn Media(&self) -> DOMString { ~"" } - pub fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { + fn SetMedia(&mut self, _media: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } - pub fn Scoped(&self) -> bool { + fn Scoped(&self) -> bool { false } - pub fn SetScoped(&self, _scoped: bool) -> ErrorResult { + fn SetScoped(&self, _scoped: bool) -> ErrorResult { Ok(()) } } @@ -80,26 +91,26 @@ pub trait StyleElementHelpers { fn parse_own_css(&self); } -impl StyleElementHelpers for JS<HTMLStyleElement> { +impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { fn parse_own_css(&self) { - let node: JS<Node> = NodeCast::from(self); - let win = window_from_node(&node); - let url = win.get().page().get_url(); + let node: &JSRef<Node> = NodeCast::from_ref(self); + let win = window_from_node(node).root(); + let url = win.deref().page().get_url(); - let data = node.get().GetTextContent(&node).expect("Element.textContent must be a string"); + let data = node.GetTextContent().expect("Element.textContent must be a string"); let sheet = parse_inline_css(url, data); - let LayoutChan(ref layout_chan) = *win.get().page().layout_chan; + let LayoutChan(ref layout_chan) = *win.deref().page().layout_chan; layout_chan.send(AddStylesheetMsg(sheet)); } } -impl VirtualMethods for JS<HTMLStyleElement> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self); - Some(~htmlelement as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, HTMLStyleElement> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self); + Some(htmlelement as &mut VirtualMethods:) } - fn child_inserted(&mut self, child: &JS<Node>) { + fn child_inserted(&mut self, child: &JSRef<Node>) { match self.super_type() { Some(ref mut s) => s.child_inserted(child), _ => (), diff --git a/src/components/script/dom/htmltablecaptionelement.rs b/src/components/script/dom/htmltablecaptionelement.rs index 0366c458f27..914208ccb73 100644 --- a/src/components/script/dom/htmltablecaptionelement.rs +++ b/src/components/script/dom/htmltablecaptionelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableCaptionElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableCaptionElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableCaptionElementTypeId; @@ -28,24 +28,29 @@ impl HTMLTableCaptionElementDerived for EventTarget { } impl HTMLTableCaptionElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableCaptionElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableCaptionElement { HTMLTableCaptionElement { htmlelement: HTMLElement::new_inherited(HTMLTableCaptionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableCaptionElement> { - let element = HTMLTableCaptionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableCaptionElement> { + let element = HTMLTableCaptionElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableCaptionElementBinding::Wrap) } } -impl HTMLTableCaptionElement { - pub fn Align(&self) -> DOMString { +pub trait HTMLTableCaptionElementMethods { + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableCaptionElementMethods for JSRef<'a, HTMLTableCaptionElement> { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltablecellelement.rs b/src/components/script/dom/htmltablecellelement.rs index b00c1d78fcd..d03e2d83d72 100644 --- a/src/components/script/dom/htmltablecellelement.rs +++ b/src/components/script/dom/htmltablecellelement.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::InheritTypes::HTMLTableCellElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::JSRef; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{ElementTypeId, HTMLTableDataCellElementTypeId, HTMLTableHeaderCellElementTypeId}; @@ -28,132 +28,164 @@ impl HTMLTableCellElementDerived for EventTarget { } impl HTMLTableCellElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLTableCellElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: &JSRef<Document>) -> HTMLTableCellElement { HTMLTableCellElement { htmlelement: HTMLElement::new_inherited(type_id, tag_name, document) } } } -impl HTMLTableCellElement { - pub fn ColSpan(&self) -> u32 { +pub trait HTMLTableCellElementMethods { + fn ColSpan(&self) -> u32; + fn SetColSpan(&self, _col_span: u32) -> ErrorResult; + fn RowSpan(&self) -> u32; + fn SetRowSpan(&self, _col_span: u32) -> ErrorResult; + fn Headers(&self) -> DOMString; + fn SetHeaders(&self, _headers: DOMString) -> ErrorResult; + fn CellIndex(&self) -> i32; + fn GetCellIndex(&self, _cell_index: i32) -> ErrorResult; + fn Abbr(&self) -> DOMString; + fn SetAbbr(&self, _abbr: DOMString) -> ErrorResult; + fn Scope(&self) -> DOMString; + fn SetScope(&self, _abbr: DOMString) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&self, _align: DOMString) -> ErrorResult; + fn Axis(&self) -> DOMString; + fn SetAxis(&self, _axis: DOMString) -> ErrorResult; + fn Height(&self) -> DOMString; + fn SetHeight(&self, _height: DOMString) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&self, _width: DOMString) -> ErrorResult; + fn Ch(&self) -> DOMString; + fn SetCh(&self, _ch: DOMString) -> ErrorResult; + fn ChOff(&self) -> DOMString; + fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult; + fn NoWrap(&self) -> bool; + fn SetNoWrap(&self, _no_wrap: bool) -> ErrorResult; + fn VAlign(&self) -> DOMString; + fn SetVAlign(&self, _valign: DOMString) -> ErrorResult; + fn BgColor(&self) -> DOMString; + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableCellElementMethods for JSRef<'a, HTMLTableCellElement> { + fn ColSpan(&self) -> u32 { 0 } - pub fn SetColSpan(&self, _col_span: u32) -> ErrorResult { + fn SetColSpan(&self, _col_span: u32) -> ErrorResult { Ok(()) } - pub fn RowSpan(&self) -> u32 { + fn RowSpan(&self) -> u32 { 0 } - pub fn SetRowSpan(&self, _col_span: u32) -> ErrorResult { + fn SetRowSpan(&self, _col_span: u32) -> ErrorResult { Ok(()) } - pub fn Headers(&self) -> DOMString { + fn Headers(&self) -> DOMString { ~"" } - pub fn SetHeaders(&self, _headers: DOMString) -> ErrorResult { + fn SetHeaders(&self, _headers: DOMString) -> ErrorResult { Ok(()) } - pub fn CellIndex(&self) -> i32 { + fn CellIndex(&self) -> i32 { 0 } - pub fn GetCellIndex(&self, _cell_index: i32) -> ErrorResult { + fn GetCellIndex(&self, _cell_index: i32) -> ErrorResult { Ok(()) } - pub fn Abbr(&self) -> DOMString { + fn Abbr(&self) -> DOMString { ~"" } - pub fn SetAbbr(&self, _abbr: DOMString) -> ErrorResult { + fn SetAbbr(&self, _abbr: DOMString) -> ErrorResult { Ok(()) } - pub fn Scope(&self) -> DOMString { + fn Scope(&self) -> DOMString { ~"" } - pub fn SetScope(&self, _abbr: DOMString) -> ErrorResult { + fn SetScope(&self, _abbr: DOMString) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&self, _align: DOMString) -> ErrorResult { + fn SetAlign(&self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Axis(&self) -> DOMString { + fn Axis(&self) -> DOMString { ~"" } - pub fn SetAxis(&self, _axis: DOMString) -> ErrorResult { + fn SetAxis(&self, _axis: DOMString) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> DOMString { + fn Height(&self) -> DOMString { ~"" } - pub fn SetHeight(&self, _height: DOMString) -> ErrorResult { + fn SetHeight(&self, _height: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&self, _width: DOMString) -> ErrorResult { + fn SetWidth(&self, _width: DOMString) -> ErrorResult { Ok(()) } - pub fn Ch(&self) -> DOMString { + fn Ch(&self) -> DOMString { ~"" } - pub fn SetCh(&self, _ch: DOMString) -> ErrorResult { + fn SetCh(&self, _ch: DOMString) -> ErrorResult { Ok(()) } - pub fn ChOff(&self) -> DOMString { + fn ChOff(&self) -> DOMString { ~"" } - pub fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult { + fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult { Ok(()) } - pub fn NoWrap(&self) -> bool { + fn NoWrap(&self) -> bool { false } - pub fn SetNoWrap(&self, _no_wrap: bool) -> ErrorResult { + fn SetNoWrap(&self, _no_wrap: bool) -> ErrorResult { Ok(()) } - pub fn VAlign(&self) -> DOMString { + fn VAlign(&self) -> DOMString { ~"" } - pub fn SetVAlign(&self, _valign: DOMString) -> ErrorResult { + fn SetVAlign(&self, _valign: DOMString) -> ErrorResult { Ok(()) } - pub fn BgColor(&self) -> DOMString { + fn BgColor(&self) -> DOMString { ~"" } - pub fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { Ok(()) } } - diff --git a/src/components/script/dom/htmltablecolelement.rs b/src/components/script/dom/htmltablecolelement.rs index cb7da24bc26..c6a02b669ad 100644 --- a/src/components/script/dom/htmltablecolelement.rs +++ b/src/components/script/dom/htmltablecolelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableColElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableColElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableColElementTypeId; @@ -28,64 +28,79 @@ impl HTMLTableColElementDerived for EventTarget { } impl HTMLTableColElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableColElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableColElement { HTMLTableColElement { htmlelement: HTMLElement::new_inherited(HTMLTableColElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableColElement> { - let element = HTMLTableColElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableColElement> { + let element = HTMLTableColElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableColElementBinding::Wrap) } } -impl HTMLTableColElement { - pub fn Span(&self) -> u32 { +pub trait HTMLTableColElementMethods { + fn Span(&self) -> u32; + fn SetSpan(&mut self, _span: u32) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Ch(&self) -> DOMString; + fn SetCh(&mut self, _ch: DOMString) -> ErrorResult; + fn ChOff(&self) -> DOMString; + fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult; + fn VAlign(&self) -> DOMString; + fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableColElementMethods for JSRef<'a, HTMLTableColElement> { + fn Span(&self) -> u32 { 0 } - pub fn SetSpan(&mut self, _span: u32) -> ErrorResult { + fn SetSpan(&mut self, _span: u32) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Ch(&self) -> DOMString { + fn Ch(&self) -> DOMString { ~"" } - pub fn SetCh(&mut self, _ch: DOMString) -> ErrorResult { + fn SetCh(&mut self, _ch: DOMString) -> ErrorResult { Ok(()) } - pub fn ChOff(&self) -> DOMString { + fn ChOff(&self) -> DOMString { ~"" } - pub fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult { + fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult { Ok(()) } - pub fn VAlign(&self) -> DOMString { + fn VAlign(&self) -> DOMString { ~"" } - pub fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult { + fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { + fn SetWidth(&mut self, _width: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltabledatacellelement.rs b/src/components/script/dom/htmltabledatacellelement.rs index 84d55945a29..c62fc8fd191 100644 --- a/src/components/script/dom/htmltabledatacellelement.rs +++ b/src/components/script/dom/htmltabledatacellelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableDataCellElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableDataCellElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLTableDataCellElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLTableDataCellElementDerived for EventTarget { } impl HTMLTableDataCellElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableDataCellElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableDataCellElement { HTMLTableDataCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited(HTMLTableDataCellElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableDataCellElement> { - let element = HTMLTableDataCellElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableDataCellElement> { + let element = HTMLTableDataCellElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableDataCellElementBinding::Wrap) } } + +pub trait HTMLTableDataCellElementMethods { +} diff --git a/src/components/script/dom/htmltableelement.rs b/src/components/script/dom/htmltableelement.rs index e4dbddd65ab..b3e040d2098 100644 --- a/src/components/script/dom/htmltableelement.rs +++ b/src/components/script/dom/htmltableelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableElementTypeId; @@ -28,111 +28,139 @@ impl HTMLTableElementDerived for EventTarget { } impl HTMLTableElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableElement { HTMLTableElement { htmlelement: HTMLElement::new_inherited(HTMLTableElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableElement> { - let element = HTMLTableElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableElement> { + let element = HTMLTableElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableElementBinding::Wrap) } } -impl HTMLTableElement { - pub fn DeleteCaption(&self) { +pub trait HTMLTableElementMethods { + fn DeleteCaption(&self); + fn DeleteTHead(&self); + fn DeleteTFoot(&self); + fn DeleteRow(&mut self, _index: i32) -> ErrorResult; + fn Sortable(&self) -> bool; + fn SetSortable(&self, _sortable: bool); + fn StopSorting(&self); + fn Align(&self) -> DOMString; + fn SetAlign(&self, _align: DOMString) -> ErrorResult; + fn Border(&self) -> DOMString; + fn SetBorder(&self, _border: DOMString) -> ErrorResult; + fn Frame(&self) -> DOMString; + fn SetFrame(&self, _frame: DOMString) -> ErrorResult; + fn Rules(&self) -> DOMString; + fn SetRules(&self, _rules: DOMString) -> ErrorResult; + fn Summary(&self) -> DOMString; + fn SetSummary(&self, _summary: DOMString) -> ErrorResult; + fn Width(&self) -> DOMString; + fn SetWidth(&self, _width: DOMString) -> ErrorResult; + fn BgColor(&self) -> DOMString; + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult; + fn CellPadding(&self) -> DOMString; + fn SetCellPadding(&self, _cell_padding: DOMString) -> ErrorResult; + fn CellSpacing(&self) -> DOMString; + fn SetCellSpacing(&self, _cell_spacing: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { + fn DeleteCaption(&self) { } - pub fn DeleteTHead(&self) { + fn DeleteTHead(&self) { } - pub fn DeleteTFoot(&self) { + fn DeleteTFoot(&self) { } - pub fn DeleteRow(&mut self, _index: i32) -> ErrorResult { + fn DeleteRow(&mut self, _index: i32) -> ErrorResult { Ok(()) } - pub fn Sortable(&self) -> bool { + fn Sortable(&self) -> bool { false } - pub fn SetSortable(&self, _sortable: bool) { + fn SetSortable(&self, _sortable: bool) { } - pub fn StopSorting(&self) { + fn StopSorting(&self) { } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&self, _align: DOMString) -> ErrorResult { + fn SetAlign(&self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Border(&self) -> DOMString { + fn Border(&self) -> DOMString { ~"" } - pub fn SetBorder(&self, _border: DOMString) -> ErrorResult { + fn SetBorder(&self, _border: DOMString) -> ErrorResult { Ok(()) } - pub fn Frame(&self) -> DOMString { + fn Frame(&self) -> DOMString { ~"" } - pub fn SetFrame(&self, _frame: DOMString) -> ErrorResult { + fn SetFrame(&self, _frame: DOMString) -> ErrorResult { Ok(()) } - pub fn Rules(&self) -> DOMString { + fn Rules(&self) -> DOMString { ~"" } - pub fn SetRules(&self, _rules: DOMString) -> ErrorResult { + fn SetRules(&self, _rules: DOMString) -> ErrorResult { Ok(()) } - pub fn Summary(&self) -> DOMString { + fn Summary(&self) -> DOMString { ~"" } - pub fn SetSummary(&self, _summary: DOMString) -> ErrorResult { + fn SetSummary(&self, _summary: DOMString) -> ErrorResult { Ok(()) } - pub fn Width(&self) -> DOMString { + fn Width(&self) -> DOMString { ~"" } - pub fn SetWidth(&self, _width: DOMString) -> ErrorResult { + fn SetWidth(&self, _width: DOMString) -> ErrorResult { Ok(()) } - pub fn BgColor(&self) -> DOMString { + fn BgColor(&self) -> DOMString { ~"" } - pub fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { Ok(()) } - pub fn CellPadding(&self) -> DOMString { + fn CellPadding(&self) -> DOMString { ~"" } - pub fn SetCellPadding(&self, _cell_padding: DOMString) -> ErrorResult { + fn SetCellPadding(&self, _cell_padding: DOMString) -> ErrorResult { Ok(()) } - pub fn CellSpacing(&self) -> DOMString { + fn CellSpacing(&self) -> DOMString { ~"" } - pub fn SetCellSpacing(&self, _cell_spacing: DOMString) -> ErrorResult { + fn SetCellSpacing(&self, _cell_spacing: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltableheadercellelement.rs b/src/components/script/dom/htmltableheadercellelement.rs index af3421a1309..1d4245fef5a 100644 --- a/src/components/script/dom/htmltableheadercellelement.rs +++ b/src/components/script/dom/htmltableheadercellelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableHeaderCellElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableHeaderCellElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLTableHeaderCellElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLTableHeaderCellElementDerived for EventTarget { } impl HTMLTableHeaderCellElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableHeaderCellElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableHeaderCellElement { HTMLTableHeaderCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited(HTMLTableHeaderCellElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableHeaderCellElement> { - let element = HTMLTableHeaderCellElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableHeaderCellElement> { + let element = HTMLTableHeaderCellElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableHeaderCellElementBinding::Wrap) } } + +pub trait HTMLTableHeaderCellElementMethods { +} diff --git a/src/components/script/dom/htmltablerowelement.rs b/src/components/script/dom/htmltablerowelement.rs index aa46e96524f..053735b5f40 100644 --- a/src/components/script/dom/htmltablerowelement.rs +++ b/src/components/script/dom/htmltablerowelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableRowElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableRowElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableRowElementTypeId; @@ -28,76 +28,94 @@ impl HTMLTableRowElementDerived for EventTarget { } impl HTMLTableRowElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableRowElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableRowElement { HTMLTableRowElement { htmlelement: HTMLElement::new_inherited(HTMLTableRowElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableRowElement> { - let element = HTMLTableRowElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableRowElement> { + let element = HTMLTableRowElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableRowElementBinding::Wrap) } } -impl HTMLTableRowElement { - pub fn RowIndex(&self) -> i32 { +pub trait HTMLTableRowElementMethods { + fn RowIndex(&self) -> i32; + fn GetRowIndex(&self) -> i32; + fn SectionRowIndex(&self) -> i32; + fn GetSectionRowIndex(&self) -> i32; + fn DeleteCell(&mut self, _index: i32) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&self, _align: DOMString) -> ErrorResult; + fn Ch(&self) -> DOMString; + fn SetCh(&self, _ch: DOMString) -> ErrorResult; + fn ChOff(&self) -> DOMString; + fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult; + fn VAlign(&self) -> DOMString; + fn SetVAlign(&self, _v_align: DOMString) -> ErrorResult; + fn BgColor(&self) -> DOMString; + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableRowElementMethods for JSRef<'a, HTMLTableRowElement> { + fn RowIndex(&self) -> i32 { 0 } - pub fn GetRowIndex(&self) -> i32 { + fn GetRowIndex(&self) -> i32 { 0 } - pub fn SectionRowIndex(&self) -> i32 { + fn SectionRowIndex(&self) -> i32 { 0 } - pub fn GetSectionRowIndex(&self) -> i32 { + fn GetSectionRowIndex(&self) -> i32 { 0 } - pub fn DeleteCell(&mut self, _index: i32) -> ErrorResult { + fn DeleteCell(&mut self, _index: i32) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&self, _align: DOMString) -> ErrorResult { + fn SetAlign(&self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Ch(&self) -> DOMString { + fn Ch(&self) -> DOMString { ~"" } - pub fn SetCh(&self, _ch: DOMString) -> ErrorResult { + fn SetCh(&self, _ch: DOMString) -> ErrorResult { Ok(()) } - pub fn ChOff(&self) -> DOMString { + fn ChOff(&self) -> DOMString { ~"" } - pub fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult { + fn SetChOff(&self, _ch_off: DOMString) -> ErrorResult { Ok(()) } - pub fn VAlign(&self) -> DOMString { + fn VAlign(&self) -> DOMString { ~"" } - pub fn SetVAlign(&self, _v_align: DOMString) -> ErrorResult { + fn SetVAlign(&self, _v_align: DOMString) -> ErrorResult { Ok(()) } - pub fn BgColor(&self) -> DOMString { + fn BgColor(&self) -> DOMString { ~"" } - pub fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { + fn SetBgColor(&self, _bg_color: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltablesectionelement.rs b/src/components/script/dom/htmltablesectionelement.rs index 2e7cbda0f71..def03af4bb2 100644 --- a/src/components/script/dom/htmltablesectionelement.rs +++ b/src/components/script/dom/htmltablesectionelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTableSectionElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableSectionElementTypeId; @@ -28,52 +28,64 @@ impl HTMLTableSectionElementDerived for EventTarget { } impl HTMLTableSectionElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableSectionElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTableSectionElement { HTMLTableSectionElement { htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableSectionElement> { - let element = HTMLTableSectionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTableSectionElement> { + let element = HTMLTableSectionElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTableSectionElementBinding::Wrap) } } -impl HTMLTableSectionElement { - pub fn DeleteRow(&mut self, _index: i32) -> ErrorResult { +pub trait HTMLTableSectionElementMethods { + fn DeleteRow(&mut self, _index: i32) -> ErrorResult; + fn Align(&self) -> DOMString; + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult; + fn Ch(&self) -> DOMString; + fn SetCh(&mut self, _ch: DOMString) -> ErrorResult; + fn ChOff(&self) -> DOMString; + fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult; + fn VAlign(&self) -> DOMString; + fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTableSectionElementMethods for JSRef<'a, HTMLTableSectionElement> { + fn DeleteRow(&mut self, _index: i32) -> ErrorResult { Ok(()) } - pub fn Align(&self) -> DOMString { + fn Align(&self) -> DOMString { ~"" } - pub fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { + fn SetAlign(&mut self, _align: DOMString) -> ErrorResult { Ok(()) } - pub fn Ch(&self) -> DOMString { + fn Ch(&self) -> DOMString { ~"" } - pub fn SetCh(&mut self, _ch: DOMString) -> ErrorResult { + fn SetCh(&mut self, _ch: DOMString) -> ErrorResult { Ok(()) } - pub fn ChOff(&self) -> DOMString { + fn ChOff(&self) -> DOMString { ~"" } - pub fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult { + fn SetChOff(&mut self, _ch_off: DOMString) -> ErrorResult { Ok(()) } - pub fn VAlign(&self) -> DOMString { + fn VAlign(&self) -> DOMString { ~"" } - pub fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult { + fn SetVAlign(&mut self, _v_align: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltemplateelement.rs b/src/components/script/dom/htmltemplateelement.rs index cc431bc117e..30bf8219d60 100644 --- a/src/components/script/dom/htmltemplateelement.rs +++ b/src/components/script/dom/htmltemplateelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTemplateElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTemplateElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLTemplateElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLTemplateElementDerived for EventTarget { } impl HTMLTemplateElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTemplateElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTemplateElement { HTMLTemplateElement { htmlelement: HTMLElement::new_inherited(HTMLTemplateElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTemplateElement> { - let element = HTMLTemplateElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTemplateElement> { + let element = HTMLTemplateElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTemplateElementBinding::Wrap) } } + +pub trait HTMLTemplateElementMethods { +} diff --git a/src/components/script/dom/htmltextareaelement.rs b/src/components/script/dom/htmltextareaelement.rs index d41b32070c1..45343a0bc02 100644 --- a/src/components/script/dom/htmltextareaelement.rs +++ b/src/components/script/dom/htmltextareaelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTextAreaElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLTextAreaElementTypeId; @@ -28,175 +28,219 @@ impl HTMLTextAreaElementDerived for EventTarget { } impl HTMLTextAreaElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTextAreaElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTextAreaElement { HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited(HTMLTextAreaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTextAreaElement> { - let element = HTMLTextAreaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTextAreaElement> { + let element = HTMLTextAreaElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTextAreaElementBinding::Wrap) } } -impl HTMLTextAreaElement { - pub fn Autofocus(&self) -> bool { +pub trait HTMLTextAreaElementMethods { + fn Autofocus(&self) -> bool; + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult; + fn Cols(&self) -> u32; + fn SetCols(&self, _cols: u32) -> ErrorResult; + fn Disabled(&self) -> bool; + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult; + fn MaxLength(&self) -> i32; + fn SetMaxLength(&self, _max_length: i32) -> ErrorResult; + fn Name(&self) -> DOMString; + fn SetName(&mut self, _name: DOMString) -> ErrorResult; + fn Placeholder(&self) -> DOMString; + fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult; + fn ReadOnly(&self) -> bool; + fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult; + fn Required(&self) -> bool; + fn SetRequired(&mut self, _required: bool) -> ErrorResult; + fn Rows(&self) -> u32; + fn SetRows(&self, _rows: u32) -> ErrorResult; + fn Wrap(&self) -> DOMString; + fn SetWrap(&mut self, _wrap: DOMString) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString); + fn DefaultValue(&self) -> DOMString; + fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult; + fn Value(&self) -> DOMString; + fn SetValue(&mut self, _value: DOMString); + fn TextLength(&self) -> u32; + fn SetTextLength(&self, _text_length: u32) -> ErrorResult; + fn WillValidate(&self) -> bool; + fn SetWillValidate(&mut self, _will_validate: bool) -> ErrorResult; + fn ValidationMessage(&self) -> DOMString; + fn CheckValidity(&self) -> bool; + fn SetCustomValidity(&self, _error: DOMString); + fn Select(&self); + fn GetSelectionStart(&self) -> Fallible<u32>; + fn SetSelectionStart(&self, _selection_start: u32) -> ErrorResult; + fn GetSelectionEnd(&self) -> Fallible<u32>; + fn SetSelectionEnd(&self, _selection_end: u32) -> ErrorResult; + fn GetSelectionDirection(&self) -> Fallible<DOMString>; + fn SetSelectionDirection(&self, _selection_direction: DOMString) -> ErrorResult; + fn SetRangeText(&self, _replacement: DOMString); +} + +impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> { + fn Autofocus(&self) -> bool { false } - pub fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { + fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult { Ok(()) } - pub fn Cols(&self) -> u32 { + fn Cols(&self) -> u32 { 0 } - pub fn SetCols(&self, _cols: u32) -> ErrorResult { + fn SetCols(&self, _cols: u32) -> ErrorResult { Ok(()) } - pub fn Disabled(&self) -> bool { + fn Disabled(&self) -> bool { false } - pub fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { + fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult { Ok(()) } - pub fn MaxLength(&self) -> i32 { + fn MaxLength(&self) -> i32 { 0 } - pub fn SetMaxLength(&self, _max_length: i32) -> ErrorResult { + fn SetMaxLength(&self, _max_length: i32) -> ErrorResult { Ok(()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&mut self, _name: DOMString) -> ErrorResult { + fn SetName(&mut self, _name: DOMString) -> ErrorResult { Ok(()) } - pub fn Placeholder(&self) -> DOMString { + fn Placeholder(&self) -> DOMString { ~"" } - pub fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult { + fn SetPlaceholder(&mut self, _placeholder: DOMString) -> ErrorResult { Ok(()) } - pub fn ReadOnly(&self) -> bool { + fn ReadOnly(&self) -> bool { false } - pub fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult { + fn SetReadOnly(&mut self, _read_only: bool) -> ErrorResult { Ok(()) } - pub fn Required(&self) -> bool { + fn Required(&self) -> bool { false } - pub fn SetRequired(&mut self, _required: bool) -> ErrorResult { + fn SetRequired(&mut self, _required: bool) -> ErrorResult { Ok(()) } - pub fn Rows(&self) -> u32 { + fn Rows(&self) -> u32 { 0 } - pub fn SetRows(&self, _rows: u32) -> ErrorResult { + fn SetRows(&self, _rows: u32) -> ErrorResult { Ok(()) } - pub fn Wrap(&self) -> DOMString { + fn Wrap(&self) -> DOMString { ~"" } - pub fn SetWrap(&mut self, _wrap: DOMString) -> ErrorResult { + fn SetWrap(&mut self, _wrap: DOMString) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) { + fn SetType(&mut self, _type: DOMString) { } - pub fn DefaultValue(&self) -> DOMString { + fn DefaultValue(&self) -> DOMString { ~"" } - pub fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult { + fn SetDefaultValue(&mut self, _default_value: DOMString) -> ErrorResult { Ok(()) } - pub fn Value(&self) -> DOMString { + fn Value(&self) -> DOMString { ~"" } - pub fn SetValue(&mut self, _value: DOMString) { + fn SetValue(&mut self, _value: DOMString) { } - pub fn TextLength(&self) -> u32 { + fn TextLength(&self) -> u32 { 0 } - pub fn SetTextLength(&self, _text_length: u32) -> ErrorResult { + fn SetTextLength(&self, _text_length: u32) -> ErrorResult { Ok(()) } - pub fn WillValidate(&self) -> bool { + fn WillValidate(&self) -> bool { false } - pub fn SetWillValidate(&mut self, _will_validate: bool) -> ErrorResult { + fn SetWillValidate(&mut self, _will_validate: bool) -> ErrorResult { Ok(()) } - pub fn ValidationMessage(&self) -> DOMString { + fn ValidationMessage(&self) -> DOMString { ~"" } - pub fn CheckValidity(&self) -> bool { + fn CheckValidity(&self) -> bool { false } - pub fn SetCustomValidity(&self, _error: DOMString) { + fn SetCustomValidity(&self, _error: DOMString) { } - pub fn Select(&self) { + fn Select(&self) { } - pub fn GetSelectionStart(&self) -> Fallible<u32> { + fn GetSelectionStart(&self) -> Fallible<u32> { Ok(0) } - pub fn SetSelectionStart(&self, _selection_start: u32) -> ErrorResult { + fn SetSelectionStart(&self, _selection_start: u32) -> ErrorResult { Ok(()) } - pub fn GetSelectionEnd(&self) -> Fallible<u32> { + fn GetSelectionEnd(&self) -> Fallible<u32> { Ok(0) } - pub fn SetSelectionEnd(&self, _selection_end: u32) -> ErrorResult { + fn SetSelectionEnd(&self, _selection_end: u32) -> ErrorResult { Ok(()) } - pub fn GetSelectionDirection(&self) -> Fallible<DOMString> { + fn GetSelectionDirection(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn SetSelectionDirection(&self, _selection_direction: DOMString) -> ErrorResult { + fn SetSelectionDirection(&self, _selection_direction: DOMString) -> ErrorResult { Ok(()) } - pub fn SetRangeText(&self, _replacement: DOMString) { + fn SetRangeText(&self, _replacement: DOMString) { } } diff --git a/src/components/script/dom/htmltimeelement.rs b/src/components/script/dom/htmltimeelement.rs index 527267d30a4..34f466419a1 100644 --- a/src/components/script/dom/htmltimeelement.rs +++ b/src/components/script/dom/htmltimeelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTimeElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTimeElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTimeElementTypeId; @@ -28,24 +28,29 @@ impl HTMLTimeElementDerived for EventTarget { } impl HTMLTimeElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTimeElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTimeElement { HTMLTimeElement { htmlelement: HTMLElement::new_inherited(HTMLTimeElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTimeElement> { - let element = HTMLTimeElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTimeElement> { + let element = HTMLTimeElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTimeElementBinding::Wrap) } } -impl HTMLTimeElement { - pub fn DateTime(&self) -> DOMString { +pub trait HTMLTimeElementMethods { + fn DateTime(&self) -> DOMString; + fn SetDateTime(&mut self, _dateTime: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTimeElementMethods for JSRef<'a, HTMLTimeElement> { + fn DateTime(&self) -> DOMString { ~"" } - pub fn SetDateTime(&mut self, _dateTime: DOMString) -> ErrorResult { + fn SetDateTime(&mut self, _dateTime: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltitleelement.rs b/src/components/script/dom/htmltitleelement.rs index 6b4b8f118bd..e327231cc4b 100644 --- a/src/components/script/dom/htmltitleelement.rs +++ b/src/components/script/dom/htmltitleelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTitleElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTitleElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTitleElementTypeId; @@ -28,24 +28,29 @@ impl HTMLTitleElementDerived for EventTarget { } impl HTMLTitleElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTitleElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTitleElement { HTMLTitleElement { htmlelement: HTMLElement::new_inherited(HTMLTitleElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTitleElement> { - let element = HTMLTitleElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTitleElement> { + let element = HTMLTitleElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTitleElementBinding::Wrap) } } -impl HTMLTitleElement { - pub fn Text(&self) -> DOMString { +pub trait HTMLTitleElementMethods { + fn Text(&self) -> DOMString; + fn SetText(&mut self, _text: DOMString) -> ErrorResult; +} + +impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> { + fn Text(&self) -> DOMString { ~"" } - pub fn SetText(&mut self, _text: DOMString) -> ErrorResult { + fn SetText(&mut self, _text: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmltrackelement.rs b/src/components/script/dom/htmltrackelement.rs index c427c799ef1..f54eec79e38 100644 --- a/src/components/script/dom/htmltrackelement.rs +++ b/src/components/script/dom/htmltrackelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLTrackElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTrackElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTrackElementTypeId; @@ -28,60 +28,74 @@ impl HTMLTrackElementDerived for EventTarget { } impl HTMLTrackElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTrackElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLTrackElement { HTMLTrackElement { htmlelement: HTMLElement::new_inherited(HTMLTrackElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTrackElement> { - let element = HTMLTrackElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLTrackElement> { + let element = HTMLTrackElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLTrackElementBinding::Wrap) } } -impl HTMLTrackElement { - pub fn Kind(&self) -> DOMString { +pub trait HTMLTrackElementMethods { + fn Kind(&self) -> DOMString; + fn SetKind(&mut self, _kind: DOMString) -> ErrorResult; + fn Src(&self) -> DOMString; + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult; + fn Srclang(&self) -> DOMString; + fn SetSrclang(&mut self, _srclang: DOMString) -> ErrorResult; + fn Label(&self) -> DOMString; + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult; + fn Default(&self) -> bool; + fn SetDefault(&mut self, _default: bool) -> ErrorResult; + fn ReadyState(&self) -> u16; +} + +impl<'a> HTMLTrackElementMethods for JSRef<'a, HTMLTrackElement> { + fn Kind(&self) -> DOMString { ~"" } - pub fn SetKind(&mut self, _kind: DOMString) -> ErrorResult { + fn SetKind(&mut self, _kind: DOMString) -> ErrorResult { Ok(()) } - pub fn Src(&self) -> DOMString { + fn Src(&self) -> DOMString { ~"" } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { Ok(()) } - pub fn Srclang(&self) -> DOMString { + fn Srclang(&self) -> DOMString { ~"" } - pub fn SetSrclang(&mut self, _srclang: DOMString) -> ErrorResult { + fn SetSrclang(&mut self, _srclang: DOMString) -> ErrorResult { Ok(()) } - pub fn Label(&self) -> DOMString { + fn Label(&self) -> DOMString { ~"" } - pub fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { + fn SetLabel(&mut self, _label: DOMString) -> ErrorResult { Ok(()) } - pub fn Default(&self) -> bool { + fn Default(&self) -> bool { false } - pub fn SetDefault(&mut self, _default: bool) -> ErrorResult { + fn SetDefault(&mut self, _default: bool) -> ErrorResult { Ok(()) } - pub fn ReadyState(&self) -> u16 { + fn ReadyState(&self) -> u16 { 0 } } diff --git a/src/components/script/dom/htmlulistelement.rs b/src/components/script/dom/htmlulistelement.rs index 8c9958fd8ff..a7e5738efd9 100644 --- a/src/components/script/dom/htmlulistelement.rs +++ b/src/components/script/dom/htmlulistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLUListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLUListElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLUListElementTypeId; @@ -28,32 +28,39 @@ impl HTMLUListElementDerived for EventTarget { } impl HTMLUListElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLUListElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLUListElement { HTMLUListElement { htmlelement: HTMLElement::new_inherited(HTMLUListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUListElement> { - let element = HTMLUListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLUListElement> { + let element = HTMLUListElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLUListElementBinding::Wrap) } } -impl HTMLUListElement { - pub fn Compact(&self) -> bool { +pub trait HTMLUListElementMethods { + fn Compact(&self) -> bool; + fn SetCompact(&mut self, _compact: bool) -> ErrorResult; + fn Type(&self) -> DOMString; + fn SetType(&mut self, _type: DOMString) -> ErrorResult; +} + +impl<'a> HTMLUListElementMethods for JSRef<'a, HTMLUListElement> { + fn Compact(&self) -> bool { false } - pub fn SetCompact(&mut self, _compact: bool) -> ErrorResult { + fn SetCompact(&mut self, _compact: bool) -> ErrorResult { Ok(()) } - pub fn Type(&self) -> DOMString { + fn Type(&self) -> DOMString { ~"" } - pub fn SetType(&mut self, _type: DOMString) -> ErrorResult { + fn SetType(&mut self, _type: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/htmlunknownelement.rs b/src/components/script/dom/htmlunknownelement.rs index a8a0b3cb41d..855b17578e5 100644 --- a/src/components/script/dom/htmlunknownelement.rs +++ b/src/components/script/dom/htmlunknownelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLUnknownElementBinding; use dom::bindings::codegen::InheritTypes::HTMLUnknownElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::element::HTMLUnknownElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -27,14 +27,17 @@ impl HTMLUnknownElementDerived for EventTarget { } impl HTMLUnknownElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLUnknownElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLUnknownElement { HTMLUnknownElement { htmlelement: HTMLElement::new_inherited(HTMLUnknownElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUnknownElement> { - let element = HTMLUnknownElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLUnknownElement> { + let element = HTMLUnknownElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLUnknownElementBinding::Wrap) } } + +pub trait HTMLUnknownElementMethods { +} diff --git a/src/components/script/dom/htmlvideoelement.rs b/src/components/script/dom/htmlvideoelement.rs index 4ef1d9c57a3..eaa4e98eb06 100644 --- a/src/components/script/dom/htmlvideoelement.rs +++ b/src/components/script/dom/htmlvideoelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::HTMLVideoElementBinding; use dom::bindings::codegen::InheritTypes::HTMLVideoElementDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLVideoElementTypeId; @@ -28,48 +28,59 @@ impl HTMLVideoElementDerived for EventTarget { } impl HTMLVideoElement { - pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLVideoElement { + pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLVideoElement { HTMLVideoElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLVideoElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLVideoElement> { - let element = HTMLVideoElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLVideoElement> { + let element = HTMLVideoElement::new_inherited(localName, document); Node::reflect_node(~element, document, HTMLVideoElementBinding::Wrap) } } -impl HTMLVideoElement { - pub fn Width(&self) -> u32 { +pub trait HTMLVideoElementMethods { + fn Width(&self) -> u32; + fn SetWidth(&mut self, _width: u32) -> ErrorResult; + fn Height(&self) -> u32; + fn SetHeight(&mut self, _height: u32) -> ErrorResult; + fn VideoWidth(&self) -> u32; + fn VideoHeight(&self) -> u32; + fn Poster(&self) -> DOMString; + fn SetPoster(&mut self, _poster: DOMString) -> ErrorResult; +} + +impl<'a> HTMLVideoElementMethods for JSRef<'a, HTMLVideoElement> { + fn Width(&self) -> u32 { 0 } - pub fn SetWidth(&mut self, _width: u32) -> ErrorResult { + fn SetWidth(&mut self, _width: u32) -> ErrorResult { Ok(()) } - pub fn Height(&self) -> u32 { + fn Height(&self) -> u32 { 0 } - pub fn SetHeight(&mut self, _height: u32) -> ErrorResult { + fn SetHeight(&mut self, _height: u32) -> ErrorResult { Ok(()) } - pub fn VideoWidth(&self) -> u32 { + fn VideoWidth(&self) -> u32 { 0 } - pub fn VideoHeight(&self) -> u32 { + fn VideoHeight(&self) -> u32 { 0 } - pub fn Poster(&self) -> DOMString { + fn Poster(&self) -> DOMString { ~"" } - pub fn SetPoster(&mut self, _poster: DOMString) -> ErrorResult { + fn SetPoster(&mut self, _poster: DOMString) -> ErrorResult { Ok(()) } } diff --git a/src/components/script/dom/location.rs b/src/components/script/dom/location.rs index 0933d324c8b..93485f0b264 100644 --- a/src/components/script/dom/location.rs +++ b/src/components/script/dom/location.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::LocationBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::window::Window; @@ -29,105 +29,134 @@ impl Location { } } - pub fn new(window: &JS<Window>, page: Rc<Page>) -> JS<Location> { + pub fn new(window: &JSRef<Window>, page: Rc<Page>) -> Temporary<Location> { reflect_dom_object(~Location::new_inherited(page), window, LocationBinding::Wrap) } +} + +pub trait LocationMethods { + fn Assign(&self, _url: DOMString); + fn Replace(&self, _url: DOMString); + fn Reload(&self); + fn Href(&self) -> DOMString; + fn SetHref(&self, _href: DOMString) -> Fallible<()>; + fn Origin(&self) -> DOMString; + fn Protocol(&self) -> DOMString; + fn SetProtocol(&self, _protocol: DOMString); + fn Username(&self) -> DOMString; + fn SetUsername(&self, _username: DOMString); + fn Password(&self) -> DOMString; + fn SetPassword(&self, _password: DOMString); + fn Host(&self) -> DOMString; + fn SetHost(&self, _host: DOMString); + fn Hostname(&self) -> DOMString; + fn SetHostname(&self, _hostname: DOMString); + fn Port(&self) -> DOMString; + fn SetPort(&self, _port: DOMString); + fn Pathname(&self) -> DOMString; + fn SetPathname(&self, _pathname: DOMString); + fn Search(&self) -> DOMString; + fn SetSearch(&self, _search: DOMString); + fn Hash(&self) -> DOMString; + fn SetHash(&self, _hash: DOMString); +} - pub fn Assign(&self, _url: DOMString) { +impl<'a> LocationMethods for JSRef<'a, Location> { + fn Assign(&self, _url: DOMString) { } - pub fn Replace(&self, _url: DOMString) { + fn Replace(&self, _url: DOMString) { } - pub fn Reload(&self) { + fn Reload(&self) { } - pub fn Href(&self) -> DOMString { + fn Href(&self) -> DOMString { self.page.get_url().to_str() } - pub fn SetHref(&self, _href: DOMString) -> Fallible<()> { + fn SetHref(&self, _href: DOMString) -> Fallible<()> { Ok(()) } - pub fn Origin(&self) -> DOMString { + fn Origin(&self) -> DOMString { ~"" } - pub fn Protocol(&self) -> DOMString { + fn Protocol(&self) -> DOMString { ~"" } - pub fn SetProtocol(&self, _protocol: DOMString) { + fn SetProtocol(&self, _protocol: DOMString) { } - pub fn Username(&self) -> DOMString { + fn Username(&self) -> DOMString { ~"" } - pub fn SetUsername(&self, _username: DOMString) { + fn SetUsername(&self, _username: DOMString) { } - pub fn Password(&self) -> DOMString { + fn Password(&self) -> DOMString { ~"" } - pub fn SetPassword(&self, _password: DOMString) { + fn SetPassword(&self, _password: DOMString) { } - pub fn Host(&self) -> DOMString { + fn Host(&self) -> DOMString { ~"" } - pub fn SetHost(&self, _host: DOMString) { + fn SetHost(&self, _host: DOMString) { } - pub fn Hostname(&self) -> DOMString { + fn Hostname(&self) -> DOMString { ~"" } - pub fn SetHostname(&self, _hostname: DOMString) { + fn SetHostname(&self, _hostname: DOMString) { } - pub fn Port(&self) -> DOMString { + fn Port(&self) -> DOMString { ~"" } - pub fn SetPort(&self, _port: DOMString) { + fn SetPort(&self, _port: DOMString) { } - pub fn Pathname(&self) -> DOMString { + fn Pathname(&self) -> DOMString { ~"" } - pub fn SetPathname(&self, _pathname: DOMString) { + fn SetPathname(&self, _pathname: DOMString) { } - pub fn Search(&self) -> DOMString { + fn Search(&self) -> DOMString { ~"" } - pub fn SetSearch(&self, _search: DOMString) { + fn SetSearch(&self, _search: DOMString) { } - pub fn Hash(&self) -> DOMString { + fn Hash(&self) -> DOMString { ~"" } - pub fn SetHash(&self, _hash: DOMString) { + fn SetHash(&self, _hash: DOMString) { } } diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs index 9db7963c2c9..fbd0abfc4d4 100644 --- a/src/components/script/dom/mouseevent.rs +++ b/src/components/script/dom/mouseevent.rs @@ -3,13 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::MouseEventBinding; -use dom::bindings::codegen::InheritTypes::MouseEventDerived; -use dom::bindings::js::JS; +use dom::bindings::codegen::InheritTypes::{UIEventCast, MouseEventDerived}; +use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable}; use dom::bindings::error::Fallible; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::event::{Event, MouseEventTypeId}; use dom::eventtarget::EventTarget; -use dom::uievent::UIEvent; +use dom::uievent::{UIEvent, UIEventMethods}; use dom::window::Window; use servo_util::str::DOMString; @@ -51,91 +51,127 @@ impl MouseEvent { } } - pub fn new(window: &JS<Window>) -> JS<MouseEvent> { + pub fn new(window: &JSRef<Window>) -> Temporary<MouseEvent> { reflect_dom_object(~MouseEvent::new_inherited(), window, MouseEventBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, + pub fn Constructor(owner: &JSRef<Window>, type_: DOMString, - init: &MouseEventBinding::MouseEventInit) -> Fallible<JS<MouseEvent>> { - let mut ev = MouseEvent::new(owner); - ev.get_mut().InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.clone(), - init.detail, init.screenX, init.screenY, - init.clientX, init.clientY, init.ctrlKey, - init.altKey, init.shiftKey, init.metaKey, - init.button, init.relatedTarget.clone()); - Ok(ev) + init: &MouseEventBinding::MouseEventInit) -> Fallible<Temporary<MouseEvent>> { + let mut ev = MouseEvent::new(owner).root(); + ev.InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.root_ref(), + init.detail, init.screenX, init.screenY, + init.clientX, init.clientY, init.ctrlKey, + init.altKey, init.shiftKey, init.metaKey, + init.button, init.relatedTarget.root_ref()); + Ok(Temporary::from_rooted(&*ev)) } +} + +pub trait MouseEventMethods { + fn ScreenX(&self) -> i32; + fn ScreenY(&self) -> i32; + fn ClientX(&self) -> i32; + fn ClientY(&self) -> i32; + fn CtrlKey(&self) -> bool; + fn ShiftKey(&self) -> bool; + fn AltKey(&self) -> bool; + fn MetaKey(&self) -> bool; + fn Button(&self) -> u16; + fn Buttons(&self)-> u16; + fn GetRelatedTarget(&self) -> Option<Temporary<EventTarget>>; + fn GetModifierState(&self, _keyArg: DOMString) -> bool; + fn InitMouseEvent(&mut self, + typeArg: DOMString, + canBubbleArg: bool, + cancelableArg: bool, + viewArg: Option<JSRef<Window>>, + detailArg: i32, + screenXArg: i32, + screenYArg: i32, + clientXArg: i32, + clientYArg: i32, + ctrlKeyArg: bool, + altKeyArg: bool, + shiftKeyArg: bool, + metaKeyArg: bool, + buttonArg: u16, + relatedTargetArg: Option<JSRef<EventTarget>>); +} - pub fn ScreenX(&self) -> i32 { +impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { + fn ScreenX(&self) -> i32 { self.screen_x } - pub fn ScreenY(&self) -> i32 { + fn ScreenY(&self) -> i32 { self.screen_y } - pub fn ClientX(&self) -> i32 { + fn ClientX(&self) -> i32 { self.client_x } - pub fn ClientY(&self) -> i32 { + fn ClientY(&self) -> i32 { self.client_y } - pub fn CtrlKey(&self) -> bool { + fn CtrlKey(&self) -> bool { self.ctrl_key } - pub fn ShiftKey(&self) -> bool { + fn ShiftKey(&self) -> bool { self.shift_key } - pub fn AltKey(&self) -> bool { + fn AltKey(&self) -> bool { self.alt_key } - pub fn MetaKey(&self) -> bool { + fn MetaKey(&self) -> bool { self.meta_key } - pub fn Button(&self) -> u16 { + fn Button(&self) -> u16 { self.button } - pub fn Buttons(&self)-> u16 { + fn Buttons(&self)-> u16 { //TODO 0 } - pub fn GetRelatedTarget(&self) -> Option<JS<EventTarget>> { - self.related_target.clone() + fn GetRelatedTarget(&self) -> Option<Temporary<EventTarget>> { + self.related_target.clone().map(|target| Temporary::new(target)) } - pub fn GetModifierState(&self, _keyArg: DOMString) -> bool { + fn GetModifierState(&self, _keyArg: DOMString) -> bool { //TODO false } - pub fn InitMouseEvent(&mut self, - typeArg: DOMString, - canBubbleArg: bool, - cancelableArg: bool, - viewArg: Option<JS<Window>>, - detailArg: i32, - screenXArg: i32, - screenYArg: i32, - clientXArg: i32, - clientYArg: i32, - ctrlKeyArg: bool, - altKeyArg: bool, - shiftKeyArg: bool, - metaKeyArg: bool, - buttonArg: u16, - relatedTargetArg: Option<JS<EventTarget>>) { - self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); + fn InitMouseEvent(&mut self, + typeArg: DOMString, + canBubbleArg: bool, + cancelableArg: bool, + viewArg: Option<JSRef<Window>>, + detailArg: i32, + screenXArg: i32, + screenYArg: i32, + clientXArg: i32, + clientYArg: i32, + ctrlKeyArg: bool, + altKeyArg: bool, + shiftKeyArg: bool, + metaKeyArg: bool, + buttonArg: u16, + relatedTargetArg: Option<JSRef<EventTarget>>) { + { + let uievent: &mut JSRef<UIEvent> = UIEventCast::from_mut_ref(self); + uievent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); + } self.screen_x = screenXArg; self.screen_y = screenYArg; self.client_x = clientXArg; @@ -145,10 +181,11 @@ impl MouseEvent { self.shift_key = shiftKeyArg; self.meta_key = metaKeyArg; self.button = buttonArg; - self.related_target = relatedTargetArg; + self.related_target.assign(relatedTargetArg); } } + impl Reflectable for MouseEvent { fn reflector<'a>(&'a self) -> &'a Reflector { self.mouseevent.reflector() diff --git a/src/components/script/dom/navigator.rs b/src/components/script/dom/navigator.rs index 39788fa7013..ec72aef0ff2 100644 --- a/src/components/script/dom/navigator.rs +++ b/src/components/script/dom/navigator.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::NavigatorBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::window::Window; @@ -21,73 +21,94 @@ impl Navigator { } } - pub fn new(window: &JS<Window>) -> JS<Navigator> { + pub fn new(window: &JSRef<Window>) -> Temporary<Navigator> { reflect_dom_object(~Navigator::new_inherited(), window, NavigatorBinding::Wrap) } +} + +pub trait NavigatorMethods { + fn DoNotTrack(&self) -> DOMString; + fn Vendor(&self) -> DOMString; + fn VendorSub(&self) -> DOMString; + fn Product(&self) -> DOMString; + fn ProductSub(&self) -> DOMString; + fn CookieEnabled(&self) -> bool; + fn GetBuildID(&self) -> Fallible<DOMString>; + fn JavaEnabled(&self) -> Fallible<bool>; + fn TaintEnabled(&self) -> bool; + fn AppName(&self) -> DOMString; + fn GetAppCodeName(&self) -> Fallible<DOMString>; + fn GetAppVersion(&self) -> Fallible<DOMString>; + fn GetPlatform(&self) -> Fallible<DOMString>; + fn GetUserAgent(&self) -> Fallible<DOMString>; + fn GetLanguage(&self) -> Option<DOMString>; + fn OnLine(&self) -> bool; +} - pub fn DoNotTrack(&self) -> DOMString { +impl<'a> NavigatorMethods for JSRef<'a, Navigator> { + fn DoNotTrack(&self) -> DOMString { ~"unspecified" } - pub fn Vendor(&self) -> DOMString { + fn Vendor(&self) -> DOMString { ~"" // Like Gecko } - pub fn VendorSub(&self) -> DOMString { + fn VendorSub(&self) -> DOMString { ~"" // Like Gecko } - pub fn Product(&self) -> DOMString { + fn Product(&self) -> DOMString { ~"Gecko" } - pub fn ProductSub(&self) -> DOMString { + fn ProductSub(&self) -> DOMString { ~"" } - pub fn CookieEnabled(&self) -> bool { + fn CookieEnabled(&self) -> bool { false } - pub fn GetBuildID(&self) -> Fallible<DOMString> { + fn GetBuildID(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn JavaEnabled(&self) -> Fallible<bool> { + fn JavaEnabled(&self) -> Fallible<bool> { Ok(false) } - pub fn TaintEnabled(&self) -> bool { + fn TaintEnabled(&self) -> bool { false } - pub fn AppName(&self) -> DOMString { + fn AppName(&self) -> DOMString { ~"Netscape" // Like Gecko/Webkit } - pub fn GetAppCodeName(&self) -> Fallible<DOMString> { + fn GetAppCodeName(&self) -> Fallible<DOMString> { Ok(~"Mozilla") // Like Gecko/Webkit } - pub fn GetAppVersion(&self) -> Fallible<DOMString> { + fn GetAppVersion(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn GetPlatform(&self) -> Fallible<DOMString> { + fn GetPlatform(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn GetUserAgent(&self) -> Fallible<DOMString> { + fn GetUserAgent(&self) -> Fallible<DOMString> { Ok(~"") } - pub fn GetLanguage(&self) -> Option<DOMString> { + fn GetLanguage(&self) -> Option<DOMString> { None } - pub fn OnLine(&self) -> bool { + fn OnLine(&self) -> bool { true } } diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index d5b43a6257f..e9a2d0ca37b 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -6,23 +6,25 @@ use dom::attr::Attr; use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTypeCast}; -use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast, ElementDerived}; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived}; use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast}; use dom::bindings::codegen::BindingDeclarations::NodeBinding::NodeConstants; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root, OptionalUnrootable}; +use dom::bindings::js::{OptionalSettable, TemporaryPushable, OptionalRootedRootable}; +use dom::bindings::js::{ResultRootable, OptionalRootable}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{ErrorResult, Fallible, NotFound, HierarchyRequest}; use dom::bindings::utils; -use dom::characterdata::CharacterData; +use dom::characterdata::{CharacterData, CharacterDataMethods}; use dom::comment::Comment; -use dom::document::{Document, HTMLDocument, NonHTMLDocument}; +use dom::document::{Document, DocumentMethods, DocumentHelpers, HTMLDocument, NonHTMLDocument}; use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; -use dom::element::{Element, ElementTypeId, HTMLAnchorElementTypeId}; +use dom::element::{Element, ElementMethods, ElementTypeId, HTMLAnchorElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::nodelist::{NodeList}; -use dom::processinginstruction::ProcessingInstruction; +use dom::processinginstruction::{ProcessingInstruction, ProcessingInstructionMethods}; use dom::text::Text; use dom::virtualmethods::{VirtualMethods, vtable_for}; use dom::window::Window; @@ -222,26 +224,161 @@ pub enum NodeTypeId { ProcessingInstructionNodeTypeId, } -pub trait INode { - fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; - fn ReplaceChild(&mut self, node: &mut JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>>; - fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; +trait PrivateNodeHelpers { + fn set_parent_node(&mut self, new_parent_node: Option<JSRef<Node>>); + fn set_first_child(&mut self, new_first_child: Option<JSRef<Node>>); + fn set_last_child(&mut self, new_last_child: Option<JSRef<Node>>); + fn set_prev_sibling(&mut self, new_prev_sibling: Option<JSRef<Node>>); + fn set_next_sibling(&mut self, new_next_sibling: Option<JSRef<Node>>); + + fn node_inserted(&self); + fn node_removed(&self); + fn add_child(&mut self, new_child: &mut JSRef<Node>, before: Option<JSRef<Node>>); + fn remove_child(&mut self, child: &mut JSRef<Node>); } -impl INode for JS<Node> { - fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().AppendChild(&mut self_node, node) +impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { + // http://dom.spec.whatwg.org/#node-is-inserted + fn node_inserted(&self) { + assert!(self.parent_node().is_some()); + let document = document_from_node(self).root(); + + if self.is_in_doc() { + for mut node in self.traverse_preorder() { + vtable_for(&mut node).bind_to_tree(); + } + } + + let mut parent = self.parent_node().root(); + parent.as_mut().map(|parent| vtable_for(&mut **parent).child_inserted(self)); + + document.deref().content_changed(); + } + + // http://dom.spec.whatwg.org/#node-is-removed + fn node_removed(&self) { + assert!(self.parent_node().is_none()); + let document = document_from_node(self).root(); + + for mut node in self.traverse_preorder() { + // XXX how about if the node wasn't in the tree in the first place? + vtable_for(&mut node).unbind_from_tree(); + } + + document.deref().content_changed(); + } + + // + // Pointer stitching + // + + /// Adds a new child to the end of this node's list of children. + /// + /// Fails unless `new_child` is disconnected from the tree. + fn add_child(&mut self, new_child: &mut JSRef<Node>, mut before: Option<JSRef<Node>>) { + assert!(new_child.parent_node().is_none()); + assert!(new_child.prev_sibling().is_none()); + assert!(new_child.next_sibling().is_none()); + match before { + Some(ref mut before) => { + // XXX Should assert that parent is self. + assert!(before.parent_node().is_some()); + match before.prev_sibling().root() { + None => { + // XXX Should assert that before is the first child of + // self. + self.set_first_child(Some(new_child.clone())); + }, + Some(mut prev_sibling) => { + prev_sibling.set_next_sibling(Some(new_child.clone())); + new_child.set_prev_sibling(Some((*prev_sibling).clone())); + }, + } + before.set_prev_sibling(Some(new_child.clone())); + new_child.set_next_sibling(Some(before.clone())); + }, + None => { + match self.last_child().root() { + None => self.set_first_child(Some(new_child.clone())), + Some(mut last_child) => { + assert!(last_child.next_sibling().is_none()); + last_child.set_next_sibling(Some(new_child.clone())); + new_child.set_prev_sibling(Some((*last_child).clone())); + } + } + + self.set_last_child(Some(new_child.clone())); + }, + } + + new_child.set_parent_node(Some(self.clone())); + } + + /// Removes the given child from this node's list of children. + /// + /// Fails unless `child` is a child of this node. (FIXME: This is not yet checked.) + fn remove_child(&mut self, child: &mut JSRef<Node>) { + assert!(child.parent_node.is_some()); + + match child.prev_sibling.root() { + None => { + let next_sibling = child.next_sibling.root(); + self.set_first_child(next_sibling.root_ref()); + } + Some(ref mut prev_sibling) => { + let next_sibling = child.next_sibling.root(); + prev_sibling.set_next_sibling(next_sibling.root_ref()); + } + } + + match child.next_sibling.root() { + None => { + let prev_sibling = child.prev_sibling.root(); + self.set_last_child(prev_sibling.root_ref()); + } + Some(ref mut next_sibling) => { + let prev_sibling = child.prev_sibling.root(); + next_sibling.set_prev_sibling(prev_sibling.root_ref()); + } + } + + child.set_prev_sibling(None); + child.set_next_sibling(None); + child.set_parent_node(None); + } + + // + // Low-level pointer stitching + // + + fn set_parent_node(&mut self, new_parent_node: Option<JSRef<Node>>) { + let doc = self.owner_doc().root(); + doc.deref().wait_until_safe_to_modify_dom(); + self.parent_node.assign(new_parent_node); + } + + fn set_first_child(&mut self, new_first_child: Option<JSRef<Node>>) { + let doc = self.owner_doc().root(); + doc.deref().wait_until_safe_to_modify_dom(); + self.first_child.assign(new_first_child); } - fn ReplaceChild(&mut self, node: &mut JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().ReplaceChild(&mut self_node, node, child) + fn set_last_child(&mut self, new_last_child: Option<JSRef<Node>>) { + let doc = self.owner_doc().root(); + doc.deref().wait_until_safe_to_modify_dom(); + self.last_child.assign(new_last_child); } - fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().RemoveChild(&mut self_node, node) + fn set_prev_sibling(&mut self, new_prev_sibling: Option<JSRef<Node>>) { + let doc = self.owner_doc().root(); + doc.deref().wait_until_safe_to_modify_dom(); + self.prev_sibling.assign(new_prev_sibling); + } + + fn set_next_sibling(&mut self, new_next_sibling: Option<JSRef<Node>>) { + let doc = self.owner_doc().root(); + doc.deref().wait_until_safe_to_modify_dom(); + self.next_sibling.assign(new_next_sibling); } } @@ -251,16 +388,21 @@ pub trait NodeHelpers { fn child_elements(&self) -> ChildElementIterator; fn following_siblings(&self) -> AbstractNodeChildrenIterator; fn is_in_doc(&self) -> bool; - fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool; - fn is_parent_of(&self, child: &JS<Node>) -> bool; + fn is_inclusive_ancestor_of(&self, parent: &JSRef<Node>) -> bool; + fn is_parent_of(&self, child: &JSRef<Node>) -> bool; fn type_id(&self) -> NodeTypeId; - fn parent_node(&self) -> Option<JS<Node>>; - fn first_child(&self) -> Option<JS<Node>>; - fn last_child(&self) -> Option<JS<Node>>; - fn prev_sibling(&self) -> Option<JS<Node>>; - fn next_sibling(&self) -> Option<JS<Node>>; + fn parent_node(&self) -> Option<Temporary<Node>>; + fn first_child(&self) -> Option<Temporary<Node>>; + fn last_child(&self) -> Option<Temporary<Node>>; + fn prev_sibling(&self) -> Option<Temporary<Node>>; + fn next_sibling(&self) -> Option<Temporary<Node>>; + + fn owner_doc(&self) -> Temporary<Document>; + fn set_owner_doc(&mut self, document: &JSRef<Document>); + + fn wait_until_safe_to_modify_dom(&self); fn is_element(&self) -> bool; fn is_document(&self) -> bool; @@ -268,11 +410,6 @@ pub trait NodeHelpers { fn is_text(&self) -> bool; fn is_anchor_element(&self) -> bool; - fn node_inserted(&self); - fn node_removed(&self); - fn add_child(&mut self, new_child: &mut JS<Node>, before: Option<JS<Node>>); - fn remove_child(&mut self, child: &mut JS<Node>); - fn get_hover_state(&self) -> bool; fn set_hover_state(&mut self, state: bool); @@ -280,18 +417,17 @@ pub trait NodeHelpers { fn dump_indent(&self, indent: uint); fn debug_str(&self) -> ~str; - fn traverse_preorder(&self) -> TreeIterator; - fn sequential_traverse_postorder(&self) -> TreeIterator; - fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator; + fn traverse_preorder<'a>(&'a self) -> TreeIterator<'a>; + fn sequential_traverse_postorder<'a>(&'a self) -> TreeIterator<'a>; + fn inclusively_following_siblings<'a>(&'a self) -> AbstractNodeChildrenIterator<'a>; - fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) -> Self; fn to_trusted_node_address(&self) -> TrustedNodeAddress; fn get_bounding_content_box(&self) -> Rect<Au>; fn get_content_boxes(&self) -> Vec<Rect<Au>>; } -impl NodeHelpers for JS<Node> { +impl<'a> NodeHelpers for JSRef<'a, Node> { /// Dumps the subtree rooted at this node, for debugging. fn dump(&self) { self.dump_indent(0); @@ -318,53 +454,40 @@ impl NodeHelpers for JS<Node> { format!("{:?}", self.type_id()) } - /// Iterates over all ancestors of this node. - fn ancestors(&self) -> AncestorIterator { - self.get().ancestors() - } - - fn children(&self) -> AbstractNodeChildrenIterator { - self.get().children() - } - - fn child_elements(&self) -> ChildElementIterator { - self.get().child_elements() - } - fn is_in_doc(&self) -> bool { - self.get().flags.is_in_doc() + self.deref().flags.is_in_doc() } /// Returns the type ID of this node. Fails if this node is borrowed mutably. fn type_id(&self) -> NodeTypeId { - self.get().type_id + self.deref().type_id } - fn parent_node(&self) -> Option<JS<Node>> { - self.get().parent_node.clone() + fn parent_node(&self) -> Option<Temporary<Node>> { + self.deref().parent_node.clone().map(|node| Temporary::new(node)) } - fn first_child(&self) -> Option<JS<Node>> { - self.get().first_child.clone() + fn first_child(&self) -> Option<Temporary<Node>> { + self.deref().first_child.clone().map(|node| Temporary::new(node)) } - fn last_child(&self) -> Option<JS<Node>> { - self.get().last_child.clone() + fn last_child(&self) -> Option<Temporary<Node>> { + self.deref().last_child.clone().map(|node| Temporary::new(node)) } /// Returns the previous sibling of this node. Fails if this node is borrowed mutably. - fn prev_sibling(&self) -> Option<JS<Node>> { - self.get().prev_sibling.clone() + fn prev_sibling(&self) -> Option<Temporary<Node>> { + self.deref().prev_sibling.clone().map(|node| Temporary::new(node)) } /// Returns the next sibling of this node. Fails if this node is borrowed mutably. - fn next_sibling(&self) -> Option<JS<Node>> { - self.get().next_sibling.clone() + fn next_sibling(&self) -> Option<Temporary<Node>> { + self.deref().next_sibling.clone().map(|node| Temporary::new(node)) } #[inline] fn is_element(&self) -> bool { - match self.type_id() { + match self.type_id { ElementNodeTypeId(..) => true, _ => false } @@ -388,7 +511,7 @@ impl NodeHelpers for JS<Node> { #[inline] fn is_doctype(&self) -> bool { - match self.type_id() { + match self.type_id { DoctypeNodeTypeId => true, _ => false } @@ -404,177 +527,58 @@ impl NodeHelpers for JS<Node> { } } - // http://dom.spec.whatwg.org/#node-is-inserted - fn node_inserted(&self) { - assert!(self.parent_node().is_some()); - let document = document_from_node(self); - - if self.is_in_doc() { - for node in self.traverse_preorder() { - vtable_for(&node).bind_to_tree(); - } - } - - self.parent_node().map(|parent| vtable_for(&parent).child_inserted(self)); - document.get().content_changed(); - } - - // http://dom.spec.whatwg.org/#node-is-removed - fn node_removed(&self) { - assert!(self.parent_node().is_none()); - let document = document_from_node(self); - - for node in self.traverse_preorder() { - // XXX how about if the node wasn't in the tree in the first place? - vtable_for(&node).unbind_from_tree(); - } - - document.get().content_changed(); - } - - // - // Pointer stitching - // - - /// Adds a new child to the end of this node's list of children. - /// - /// Fails unless `new_child` is disconnected from the tree. - fn add_child(&mut self, new_child: &mut JS<Node>, before: Option<JS<Node>>) { - assert!(new_child.parent_node().is_none()); - assert!(new_child.prev_sibling().is_none()); - assert!(new_child.next_sibling().is_none()); - match before { - Some(mut before) => { - // XXX Should assert that parent is self. - assert!(before.parent_node().is_some()); - match before.prev_sibling() { - None => { - // XXX Should assert that before is the first child of - // self. - self.get_mut().set_first_child(Some(new_child.clone())); - }, - Some(mut prev_sibling) => { - prev_sibling.get_mut().set_next_sibling(Some(new_child.clone())); - new_child.get_mut().set_prev_sibling(Some(prev_sibling.clone())); - }, - } - before.get_mut().set_prev_sibling(Some(new_child.clone())); - new_child.get_mut().set_next_sibling(Some(before.clone())); - }, - None => { - match self.last_child() { - None => self.get_mut().set_first_child(Some(new_child.clone())), - Some(mut last_child) => { - assert!(last_child.next_sibling().is_none()); - last_child.get_mut().set_next_sibling(Some(new_child.clone())); - new_child.get_mut().set_prev_sibling(Some(last_child.clone())); - } - } - - self.get_mut().set_last_child(Some(new_child.clone())); - }, - } - - new_child.get_mut().set_parent_node(Some(self.clone())); - } - - /// Removes the given child from this node's list of children. - /// - /// Fails unless `child` is a child of this node. (FIXME: This is not yet checked.) - fn remove_child(&mut self, child: &mut JS<Node>) { - let this_node = self.get_mut(); - let child_node = child.get_mut(); - assert!(child_node.parent_node.is_some()); - - match child_node.prev_sibling { - None => this_node.set_first_child(child_node.next_sibling.clone()), - Some(ref mut prev_sibling) => { - let prev_sibling_node = prev_sibling.get_mut(); - prev_sibling_node.set_next_sibling(child_node.next_sibling.clone()); - } - } - - match child_node.next_sibling { - None => this_node.set_last_child(child_node.prev_sibling.clone()), - Some(ref mut next_sibling) => { - let next_sibling_node = next_sibling.get_mut(); - next_sibling_node.set_prev_sibling(child_node.prev_sibling.clone()); - } - } - - child_node.set_prev_sibling(None); - child_node.set_next_sibling(None); - child_node.set_parent_node(None); - } - fn get_hover_state(&self) -> bool { - self.get().flags.get_in_hover_state() + self.flags.get_in_hover_state() } fn set_hover_state(&mut self, state: bool) { - self.get_mut().flags.set_is_in_hover_state(state); + self.flags.set_is_in_hover_state(state); } /// Iterates over this node and all its descendants, in preorder. - fn traverse_preorder(&self) -> TreeIterator { + fn traverse_preorder<'a>(&'a self) -> TreeIterator<'a> { let mut nodes = vec!(); gather_abstract_nodes(self, &mut nodes, false); TreeIterator::new(nodes) } /// Iterates over this node and all its descendants, in postorder. - fn sequential_traverse_postorder(&self) -> TreeIterator { + fn sequential_traverse_postorder<'a>(&'a self) -> TreeIterator<'a> { let mut nodes = vec!(); gather_abstract_nodes(self, &mut nodes, true); TreeIterator::new(nodes) } - fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator { + fn inclusively_following_siblings<'a>(&'a self) -> AbstractNodeChildrenIterator<'a> { AbstractNodeChildrenIterator { current_node: Some(self.clone()), } } - fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool { - self == parent || parent.ancestors().any(|ancestor| ancestor == *self) + fn is_inclusive_ancestor_of(&self, parent: &JSRef<Node>) -> bool { + self == parent || parent.ancestors().any(|ancestor| &ancestor == self) } fn following_siblings(&self) -> AbstractNodeChildrenIterator { AbstractNodeChildrenIterator { - current_node: self.next_sibling(), + current_node: self.next_sibling().root().map(|next| next.deref().clone()), } } - fn is_parent_of(&self, child: &JS<Node>) -> bool { + fn is_parent_of(&self, child: &JSRef<Node>) -> bool { match child.parent_node() { - Some(ref parent) if parent == self => true, + Some(ref parent) if *parent == Temporary::from_rooted(self) => true, _ => false } } - /// If the given untrusted node address represents a valid DOM node in the given runtime, - /// returns it. - fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) - -> JS<Node> { - unsafe { - let candidate: uintptr_t = cast::transmute(candidate); - let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, - candidate); - if object.is_null() { - fail!("Attempted to create a `JS<Node>` from an invalid pointer!") - } - let boxed_node: *mut Node = utils::unwrap(object); - JS::from_raw(boxed_node) - } - } - fn to_trusted_node_address(&self) -> TrustedNodeAddress { - TrustedNodeAddress(self.get() as *Node as *libc::c_void) + TrustedNodeAddress(self.deref() as *Node as *libc::c_void) } fn get_bounding_content_box(&self) -> Rect<Au> { - let window = window_from_node(self); - let page = window.get().page(); + let window = window_from_node(self).root(); + let page = window.deref().page(); let (chan, port) = channel(); let addr = self.to_trusted_node_address(); let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(addr, chan), port); @@ -582,63 +586,180 @@ impl NodeHelpers for JS<Node> { } fn get_content_boxes(&self) -> Vec<Rect<Au>> { - let window = window_from_node(self); - let page = window.get().page(); + let window = window_from_node(self).root(); + let page = window.deref().page(); let (chan, port) = channel(); let addr = self.to_trusted_node_address(); let ContentBoxesResponse(rects) = page.query_layout(ContentBoxesQuery(addr, chan), port); rects } + + fn ancestors(&self) -> AncestorIterator { + AncestorIterator { + current: self.parent_node.clone().map(|node| (*node.root()).clone()), + } + } + + fn owner_doc(&self) -> Temporary<Document> { + Temporary::new(self.owner_doc.get_ref().clone()) + } + + fn set_owner_doc(&mut self, document: &JSRef<Document>) { + self.owner_doc.assign(Some(document.clone())); + } + + fn children(&self) -> AbstractNodeChildrenIterator { + AbstractNodeChildrenIterator { + current_node: self.first_child.clone().map(|node| (*node.root()).clone()), + } + } + + fn child_elements(&self) -> ChildElementIterator { + self.children() + .filter(|node| { + node.is_element() + }) + .map(|node| { + let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap(); + elem.clone() + }) + } + + fn wait_until_safe_to_modify_dom(&self) { + let document = self.owner_doc().root(); + document.deref().wait_until_safe_to_modify_dom(); + } + +} + +/// If the given untrusted node address represents a valid DOM node in the given runtime, +/// returns it. +pub fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) + -> Temporary<Node> { + unsafe { + let candidate: uintptr_t = cast::transmute(candidate); + let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, + candidate); + if object.is_null() { + fail!("Attempted to create a `JS<Node>` from an invalid pointer!") + } + let boxed_node: *mut Node = utils::unwrap(object); + Temporary::new(JS::from_raw(boxed_node)) + } +} + +pub trait LayoutNodeHelpers { + unsafe fn type_id_for_layout(&self) -> NodeTypeId; + + unsafe fn parent_node_ref<'a>(&'a self) -> Option<&'a JS<Node>>; + unsafe fn first_child_ref<'a>(&'a self) -> Option<&'a JS<Node>>; + unsafe fn last_child_ref<'a>(&'a self) -> Option<&'a JS<Node>>; + unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>>; + unsafe fn next_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>>; + + unsafe fn owner_doc_for_layout<'a>(&'a self) -> &'a JS<Document>; + + unsafe fn is_element_for_layout(&self) -> bool; } +impl LayoutNodeHelpers for JS<Node> { + unsafe fn type_id_for_layout(&self) -> NodeTypeId { + (*self.unsafe_get()).type_id + } + + unsafe fn is_element_for_layout(&self) -> bool { + (*self.unsafe_get()).is_element() + } + + #[inline] + unsafe fn parent_node_ref<'a>(&'a self) -> Option<&'a JS<Node>> { + (*self.unsafe_get()).parent_node.as_ref() + } + + #[inline] + unsafe fn first_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> { + (*self.unsafe_get()).first_child.as_ref() + } + + #[inline] + unsafe fn last_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> { + (*self.unsafe_get()).last_child.as_ref() + } + + #[inline] + unsafe fn prev_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> { + (*self.unsafe_get()).prev_sibling.as_ref() + } + + #[inline] + unsafe fn next_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> { + (*self.unsafe_get()).next_sibling.as_ref() + } + + unsafe fn owner_doc_for_layout<'a>(&'a self) -> &'a JS<Document> { + (*self.unsafe_get()).owner_doc.get_ref() + } +} + +pub trait RawLayoutNodeHelpers { + unsafe fn get_hover_state_for_layout(&self) -> bool; +} + +impl RawLayoutNodeHelpers for Node { + unsafe fn get_hover_state_for_layout(&self) -> bool { + self.flags.get_in_hover_state() + } +} + + // // Iteration and traversal // -pub type ChildElementIterator<'a> = Map<'a, JS<Node>, - JS<Element>, - Filter<'a, JS<Node>, AbstractNodeChildrenIterator>>; +pub type ChildElementIterator<'a, 'b> = Map<'a, JSRef<'b, Node>, + JSRef<'b, Element>, + Filter<'a, JSRef<'b, Node>, AbstractNodeChildrenIterator<'b>>>; -pub struct AbstractNodeChildrenIterator { - current_node: Option<JS<Node>>, +pub struct AbstractNodeChildrenIterator<'a> { + current_node: Option<JSRef<'a, Node>>, } -impl Iterator<JS<Node>> for AbstractNodeChildrenIterator { - fn next(&mut self) -> Option<JS<Node>> { +impl<'a> Iterator<JSRef<'a, Node>> for AbstractNodeChildrenIterator<'a> { + fn next(&mut self) -> Option<JSRef<'a, Node>> { let node = self.current_node.clone(); self.current_node = node.clone().and_then(|node| { - node.next_sibling() + node.next_sibling().map(|node| (*node.root()).clone()) }); node } } -pub struct AncestorIterator { - current: Option<JS<Node>>, +pub struct AncestorIterator<'a> { + current: Option<JSRef<'a, Node>>, } -impl Iterator<JS<Node>> for AncestorIterator { - fn next(&mut self) -> Option<JS<Node>> { +impl<'a> Iterator<JSRef<'a, Node>> for AncestorIterator<'a> { + fn next(&mut self) -> Option<JSRef<'a, Node>> { if self.current.is_none() { return None; } // FIXME: Do we need two clones here? let x = self.current.get_ref().clone(); - self.current = x.parent_node(); - Some(x.clone()) + self.current = x.parent_node().map(|node| (*node.root()).clone()); + Some(x) } } // FIXME: Do this without precomputing a vector of refs. // Easy for preorder; harder for postorder. -pub struct TreeIterator { - nodes: Vec<JS<Node>>, +pub struct TreeIterator<'a> { + nodes: Vec<JSRef<'a, Node>>, index: uint, } -impl TreeIterator { - fn new(nodes: Vec<JS<Node>>) -> TreeIterator { +impl<'a> TreeIterator<'a> { + fn new(nodes: Vec<JSRef<'a, Node>>) -> TreeIterator<'a> { TreeIterator { nodes: nodes, index: 0, @@ -646,8 +767,8 @@ impl TreeIterator { } } -impl Iterator<JS<Node>> for TreeIterator { - fn next(&mut self) -> Option<JS<Node>> { +impl<'a> Iterator<JSRef<'a, Node>> for TreeIterator<'a> { + fn next(&mut self) -> Option<JSRef<'a, Node>> { if self.index >= self.nodes.len() { None } else { @@ -667,9 +788,11 @@ pub struct NodeIterator { } impl NodeIterator { - pub fn new(start_node: JS<Node>, include_start: bool, include_descendants_of_void: bool) -> NodeIterator { + pub fn new<'a>(start_node: &JSRef<'a, Node>, + include_start: bool, + include_descendants_of_void: bool) -> NodeIterator { NodeIterator { - start_node: start_node, + start_node: start_node.unrooted(), current_node: None, depth: 0, include_start: include_start, @@ -677,51 +800,54 @@ impl NodeIterator { } } - fn next_child(&self, node: &JS<Node>) -> Option<JS<Node>> { + fn next_child<'b>(&self, node: &JSRef<'b, Node>) -> Option<JSRef<Node>> { if !self.include_descendants_of_void && node.is_element() { - let elem: JS<Element> = ElementCast::to(node).unwrap(); - if elem.get().is_void() { + let elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + if elem.deref().is_void() { None } else { - node.first_child() + node.first_child().map(|child| (*child.root()).clone()) } } else { - node.first_child() + node.first_child().map(|child| (*child.root()).clone()) } } } -impl Iterator<JS<Node>> for NodeIterator { - fn next(&mut self) -> Option<JS<Node>> { - self.current_node = match self.current_node { +impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator { + fn next(&mut self) -> Option<JSRef<Node>> { + self.current_node = match self.current_node.as_ref().map(|node| node.root()) { None => { if self.include_start { Some(self.start_node.clone()) } else { - self.next_child(&self.start_node) + self.next_child(&*self.start_node.root()) + .map(|child| child.unrooted()) } }, - Some(ref node) => { - match self.next_child(node) { + Some(node) => { + match self.next_child(&*node) { Some(child) => { self.depth += 1; - Some(child.clone()) + Some(child.unrooted()) }, - None if node == &self.start_node => None, + None if node.deref().unrooted() == self.start_node => None, None => { - match node.next_sibling() { - Some(sibling) => Some(sibling), + match node.deref().next_sibling().root() { + Some(sibling) => Some(sibling.deref().unrooted()), None => { - let mut candidate = node.clone(); + let mut candidate = node.deref().clone(); while candidate.next_sibling().is_none() { - candidate = candidate.parent_node().expect("Got to root without reaching start node"); + candidate = (*candidate.parent_node() + .expect("Got to root without reaching start node") + .root()).clone(); self.depth -= 1; - if candidate == self.start_node { + if candidate.unrooted() == self.start_node { break; } } - if candidate != self.start_node { - candidate.next_sibling() + if candidate.unrooted() != self.start_node { + candidate.next_sibling().map(|node| node.root().unrooted()) } else { None } @@ -731,11 +857,11 @@ impl Iterator<JS<Node>> for NodeIterator { } } }; - self.current_node.clone() + self.current_node.clone().map(|node| (*node.root()).clone()) } } -fn gather_abstract_nodes(cur: &JS<Node>, refs: &mut Vec<JS<Node>>, postorder: bool) { +fn gather_abstract_nodes<'a>(cur: &JSRef<'a, Node>, refs: &mut Vec<JSRef<'a, Node>>, postorder: bool) { if !postorder { refs.push(cur.clone()); } @@ -757,55 +883,27 @@ pub enum CloneChildrenFlag { fn as_uintptr<T>(t: &T) -> uintptr_t { t as *T as uintptr_t } impl Node { - pub fn ancestors(&self) -> AncestorIterator { - AncestorIterator { - current: self.parent_node.clone(), - } - } - - pub fn owner_doc<'a>(&'a self) -> &'a JS<Document> { - self.owner_doc.get_ref() - } - - pub fn set_owner_doc(&mut self, document: &JS<Document>) { - self.owner_doc = Some(document.clone()); - } - - pub fn children(&self) -> AbstractNodeChildrenIterator { - AbstractNodeChildrenIterator { - current_node: self.first_child.clone(), - } - } - - pub fn child_elements(&self) -> ChildElementIterator { - self.children() - .filter(|node| node.is_element()) - .map(|node| { - let elem: JS<Element> = ElementCast::to(&node).unwrap(); - elem - }) - } - pub fn reflect_node<N: Reflectable+NodeBase> (node: ~N, - document: &JS<Document>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~N) -> JS<N>) - -> JS<N> { + document: &JSRef<Document>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~N) -> JS<N>) + -> Temporary<N> { assert!(node.reflector().get_jsobject().is_null()); - let node = reflect_dom_object(node, &document.get().window, wrap_fn); - assert!(node.reflector().get_jsobject().is_not_null()); - node + let window = document.deref().window.root(); + let node = reflect_dom_object(node, &window.root_ref(), wrap_fn).root(); + assert!(node.deref().reflector().get_jsobject().is_not_null()); + Temporary::from_rooted(&*node) } - pub fn new_inherited(type_id: NodeTypeId, doc: JS<Document>) -> Node { - Node::new_(type_id, Some(doc)) + pub fn new_inherited(type_id: NodeTypeId, doc: &JSRef<Document>) -> Node { + Node::new_(type_id, Some(doc.clone())) } pub fn new_without_doc(type_id: NodeTypeId) -> Node { Node::new_(type_id, None) } - fn new_(type_id: NodeTypeId, doc: Option<JS<Document>>) -> Node { + fn new_(type_id: NodeTypeId, doc: Option<JSRef<Document>>) -> Node { Node { eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)), type_id: type_id, @@ -816,7 +914,7 @@ impl Node { next_sibling: None, prev_sibling: None, - owner_doc: doc, + owner_doc: doc.unrooted(), child_list: None, flags: NodeFlags::new(type_id), @@ -825,227 +923,21 @@ impl Node { } } - /// Sends layout data, if any, back to the script task to be destroyed. - pub unsafe fn reap_layout_data(&mut self) { - if self.layout_data.is_present() { - let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new()); - let layout_chan = layout_data.take_chan(); - match layout_chan { - None => {} - Some(chan) => { - let LayoutChan(chan) = chan; - chan.send(ReapLayoutDataMsg(layout_data)) - }, - } - } - } - - // http://dom.spec.whatwg.org/#dom-node-nodetype - pub fn NodeType(&self) -> u16 { - match self.type_id { - ElementNodeTypeId(_) => NodeConstants::ELEMENT_NODE, - TextNodeTypeId => NodeConstants::TEXT_NODE, - ProcessingInstructionNodeTypeId => NodeConstants::PROCESSING_INSTRUCTION_NODE, - CommentNodeTypeId => NodeConstants::COMMENT_NODE, - DocumentNodeTypeId => NodeConstants::DOCUMENT_NODE, - DoctypeNodeTypeId => NodeConstants::DOCUMENT_TYPE_NODE, - DocumentFragmentNodeTypeId => NodeConstants::DOCUMENT_FRAGMENT_NODE, - } - } - - // http://dom.spec.whatwg.org/#dom-node-nodename - pub fn NodeName(&self, abstract_self: &JS<Node>) -> DOMString { - match self.type_id { - ElementNodeTypeId(..) => { - let elem: JS<Element> = ElementCast::to(abstract_self).unwrap(); - elem.get().TagName() - } - TextNodeTypeId => ~"#text", - ProcessingInstructionNodeTypeId => { - let processing_instruction: JS<ProcessingInstruction> = - ProcessingInstructionCast::to(abstract_self).unwrap(); - processing_instruction.get().Target() - } - CommentNodeTypeId => ~"#comment", - DoctypeNodeTypeId => { - let doctype: JS<DocumentType> = DocumentTypeCast::to(abstract_self).unwrap(); - doctype.get().name.clone() - }, - DocumentFragmentNodeTypeId => ~"#document-fragment", - DocumentNodeTypeId => ~"#document" - } - } - - // http://dom.spec.whatwg.org/#dom-node-baseuri - pub fn GetBaseURI(&self) -> Option<DOMString> { - // FIXME (#1824) implement. - None - } - - // http://dom.spec.whatwg.org/#dom-node-ownerdocument - pub fn GetOwnerDocument(&self) -> Option<JS<Document>> { - match self.type_id { - ElementNodeTypeId(..) | - CommentNodeTypeId | - TextNodeTypeId | - ProcessingInstructionNodeTypeId | - DoctypeNodeTypeId | - DocumentFragmentNodeTypeId => Some(self.owner_doc().clone()), - DocumentNodeTypeId => None - } - } - - // http://dom.spec.whatwg.org/#dom-node-parentnode - pub fn GetParentNode(&self) -> Option<JS<Node>> { - self.parent_node.clone() - } - - // http://dom.spec.whatwg.org/#dom-node-parentelement - pub fn GetParentElement(&self) -> Option<JS<Element>> { - self.parent_node.clone().and_then(|parent| ElementCast::to(&parent)) - } - - // http://dom.spec.whatwg.org/#dom-node-haschildnodes - pub fn HasChildNodes(&self) -> bool { - self.first_child.is_some() - } - - // http://dom.spec.whatwg.org/#dom-node-childnodes - pub fn ChildNodes(&mut self, abstract_self: &JS<Node>) -> JS<NodeList> { - match self.child_list { - None => { - let doc = self.owner_doc().clone(); - let doc = doc.get(); - let list = NodeList::new_child_list(&doc.window, abstract_self); - self.child_list = Some(list.clone()); - list - } - Some(ref list) => list.clone() - } - } - - // http://dom.spec.whatwg.org/#dom-node-firstchild - pub fn GetFirstChild(&self) -> Option<JS<Node>> { - self.first_child.clone() - } - - // http://dom.spec.whatwg.org/#dom-node-lastchild - pub fn GetLastChild(&self) -> Option<JS<Node>> { - self.last_child.clone() - } - - // http://dom.spec.whatwg.org/#dom-node-previoussibling - pub fn GetPreviousSibling(&self) -> Option<JS<Node>> { - self.prev_sibling.clone() - } - - // http://dom.spec.whatwg.org/#dom-node-nextsibling - pub fn GetNextSibling(&self) -> Option<JS<Node>> { - self.next_sibling.clone() - } - - // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn GetNodeValue(&self, abstract_self: &JS<Node>) -> Option<DOMString> { - match self.type_id { - CommentNodeTypeId | - TextNodeTypeId | - ProcessingInstructionNodeTypeId => { - let chardata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); - Some(chardata.get().Data()) - } - _ => { - None - } - } - } - - // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn SetNodeValue(&mut self, abstract_self: &mut JS<Node>, val: Option<DOMString>) - -> ErrorResult { - match self.type_id { - CommentNodeTypeId | - TextNodeTypeId | - ProcessingInstructionNodeTypeId => { - self.SetTextContent(abstract_self, val) - } - _ => Ok(()) - } - } - - // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn GetTextContent(&self, abstract_self: &JS<Node>) -> Option<DOMString> { - match self.type_id { - DocumentFragmentNodeTypeId | - ElementNodeTypeId(..) => { - let mut content = ~""; - for node in abstract_self.traverse_preorder() { - if node.is_text() { - let text: JS<Text> = TextCast::to(&node).unwrap(); - content.push_str(text.get().characterdata.data.as_slice()); - } - } - Some(content) - } - CommentNodeTypeId | - TextNodeTypeId | - ProcessingInstructionNodeTypeId => { - let characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); - Some(characterdata.get().Data()) - } - DoctypeNodeTypeId | - DocumentNodeTypeId => { - None - } - } - } - - // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn SetTextContent(&mut self, abstract_self: &mut JS<Node>, value: Option<DOMString>) - -> ErrorResult { - let value = null_str_as_empty(&value); - match self.type_id { - DocumentFragmentNodeTypeId | - ElementNodeTypeId(..) => { - // Step 1-2. - let node = if value.len() == 0 { - None - } else { - let document = self.owner_doc(); - Some(NodeCast::from(&document.get().CreateTextNode(document, value))) - }; - // Step 3. - Node::replace_all(node, abstract_self); - } - CommentNodeTypeId | - TextNodeTypeId | - ProcessingInstructionNodeTypeId => { - self.wait_until_safe_to_modify_dom(); - - let mut characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); - characterdata.get_mut().data = value.clone(); - - // Notify the document that the content of this node is different - let document = self.owner_doc(); - document.get().content_changed(); - } - DoctypeNodeTypeId | - DocumentNodeTypeId => {} - } - Ok(()) - } - // http://dom.spec.whatwg.org/#concept-node-adopt - pub fn adopt(node: &mut JS<Node>, document: &JS<Document>) { + pub fn adopt(node: &mut JSRef<Node>, document: &JSRef<Document>) { // Step 1. - match node.parent_node() { - Some(ref mut parent) => Node::remove(node, parent, Unsuppressed), + match node.parent_node().root() { + Some(mut parent) => { + Node::remove(node, &mut *parent, Unsuppressed); + } None => (), } // Step 2. - if document_from_node(node) != *document { + let node_doc = document_from_node(node).root(); + if &*node_doc != document { for mut descendant in node.traverse_preorder() { - descendant.get_mut().set_owner_doc(document); + descendant.set_owner_doc(document); } } @@ -1054,8 +946,8 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-insert - fn pre_insert(node: &mut JS<Node>, parent: &mut JS<Node>, child: Option<JS<Node>>) - -> Fallible<JS<Node>> { + fn pre_insert(node: &mut JSRef<Node>, parent: &mut JSRef<Node>, child: Option<JSRef<Node>>) + -> Fallible<Temporary<Node>> { // Step 1. match parent.type_id() { DocumentNodeTypeId | @@ -1078,13 +970,13 @@ impl Node { // Step 4-5. match node.type_id() { TextNodeTypeId => { - match node.parent_node() { + match node.parent_node().root() { Some(ref parent) if parent.is_document() => return Err(HierarchyRequest), _ => () } } DoctypeNodeTypeId => { - match node.parent_node() { + match node.parent_node().root() { Some(ref parent) if !parent.is_document() => return Err(HierarchyRequest), _ => () } @@ -1175,24 +1067,25 @@ impl Node { // Step 7-8. let referenceChild = match child { - Some(ref child) if child == node => node.next_sibling(), + Some(ref child) if child == node => node.next_sibling().map(|node| (*node.root()).clone()), _ => child }; // Step 9. - Node::adopt(node, &document_from_node(parent)); + let document = document_from_node(parent).root(); + Node::adopt(node, &*document); // Step 10. Node::insert(node, parent, referenceChild, Unsuppressed); // Step 11. - return Ok(node.clone()) + return Ok(Temporary::from_rooted(node)) } // http://dom.spec.whatwg.org/#concept-node-insert - fn insert(node: &mut JS<Node>, - parent: &mut JS<Node>, - child: Option<JS<Node>>, + fn insert(node: &mut JSRef<Node>, + parent: &mut JSRef<Node>, + child: Option<JSRef<Node>>, suppress_observers: SuppressObserver) { // XXX assert owner_doc // Step 1-3: ranges. @@ -1217,7 +1110,7 @@ impl Node { // Step 8. for node in nodes.mut_iter() { parent.add_child(node, child.clone()); - node.get_mut().flags.set_is_in_doc(parent.is_in_doc()); + node.deref_mut().flags.set_is_in_doc(parent.is_in_doc()); } // Step 9. @@ -1232,15 +1125,19 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-replace-all - pub fn replace_all(mut node: Option<JS<Node>>, parent: &mut JS<Node>) { + fn replace_all(mut node: Option<JSRef<Node>>, parent: &mut JSRef<Node>) { + // Step 1. match node { - Some(ref mut node) => Node::adopt(node, &document_from_node(parent)), + Some(ref mut node) => { + let document = document_from_node(parent).root(); + Node::adopt(node, &*document); + } None => (), } // Step 2. - let removedNodes: Vec<JS<Node>> = parent.children().collect(); + let removedNodes: Vec<JSRef<Node>> = parent.children().collect(); // Step 3. let addedNodes = match node { @@ -1274,10 +1171,10 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-remove - fn pre_remove(child: &mut JS<Node>, parent: &mut JS<Node>) -> Fallible<JS<Node>> { + fn pre_remove(child: &mut JSRef<Node>, parent: &mut JSRef<Node>) -> Fallible<Temporary<Node>> { // Step 1. match child.parent_node() { - Some(ref node) if node != parent => return Err(NotFound), + Some(ref node) if *node != Temporary::from_rooted(parent) => return Err(NotFound), _ => () } @@ -1285,18 +1182,18 @@ impl Node { Node::remove(child, parent, Unsuppressed); // Step 3. - Ok(child.clone()) + Ok(Temporary::from_rooted(child)) } // http://dom.spec.whatwg.org/#concept-node-remove - fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) { - assert!(node.parent_node().map_or(false, |ref node_parent| node_parent == parent)); + fn remove(node: &mut JSRef<Node>, parent: &mut JSRef<Node>, suppress_observers: SuppressObserver) { + assert!(node.parent_node().map_or(false, |node_parent| node_parent == Temporary::from_rooted(parent))); // Step 1-5: ranges. // Step 6-7: mutation observers. // Step 8. parent.remove_child(node); - node.get_mut().flags.set_is_in_doc(false); + node.deref_mut().flags.set_is_in_doc(false); // Step 9. match suppress_observers { @@ -1306,100 +1203,103 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-clone - pub fn clone(node: &JS<Node>, maybe_doc: Option<&JS<Document>>, - clone_children: CloneChildrenFlag) -> JS<Node> { + pub fn clone(node: &JSRef<Node>, maybe_doc: Option<&JSRef<Document>>, + clone_children: CloneChildrenFlag) -> Temporary<Node> { + // Step 1. let mut document = match maybe_doc { - Some(doc) => doc.clone(), - None => node.get().owner_doc().clone() + Some(doc) => doc.unrooted().root(), + None => node.owner_doc().root() }; // Step 2. // XXXabinader: clone() for each node as trait? - let mut copy: JS<Node> = match node.type_id() { + let mut copy: Root<Node> = match node.type_id() { DoctypeNodeTypeId => { - let doctype: JS<DocumentType> = DocumentTypeCast::to(node).unwrap(); - let doctype = doctype.get(); + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); + let doctype = doctype.deref(); let doctype = DocumentType::new(doctype.name.clone(), Some(doctype.public_id.clone()), - Some(doctype.system_id.clone()), &document); - NodeCast::from(&doctype) + Some(doctype.system_id.clone()), &*document); + NodeCast::from_unrooted(doctype) }, DocumentFragmentNodeTypeId => { - let doc_fragment = DocumentFragment::new(&document); - NodeCast::from(&doc_fragment) + let doc_fragment = DocumentFragment::new(&*document); + NodeCast::from_unrooted(doc_fragment) }, CommentNodeTypeId => { - let comment: JS<Comment> = CommentCast::to(node).unwrap(); - let comment = comment.get(); - let comment = Comment::new(comment.characterdata.data.clone(), &document); - NodeCast::from(&comment) + let comment: &JSRef<Comment> = CommentCast::to_ref(node).unwrap(); + let comment = comment.deref(); + let comment = Comment::new(comment.characterdata.data.clone(), &*document); + NodeCast::from_unrooted(comment) }, DocumentNodeTypeId => { - let document: JS<Document> = DocumentCast::to(node).unwrap(); - let document = document.get(); + let document: &JSRef<Document> = DocumentCast::to_ref(node).unwrap(); let is_html_doc = match document.is_html_document { true => HTMLDocument, false => NonHTMLDocument }; - let document = Document::new(&document.window, Some(document.url().clone()), + let window = document.window.root(); + let document = Document::new(&*window, Some(document.url().clone()), is_html_doc, None); - NodeCast::from(&document) + NodeCast::from_unrooted(document) }, ElementNodeTypeId(..) => { - let element: JS<Element> = ElementCast::to(node).unwrap(); - let element = element.get(); - let element = build_element_from_tag(element.local_name.clone(), &document); - NodeCast::from(&element) + let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let element = element.deref(); + let element = build_element_from_tag(element.local_name.clone(), &*document); + NodeCast::from_unrooted(element) }, TextNodeTypeId => { - let text: JS<Text> = TextCast::to(node).unwrap(); - let text = text.get(); - let text = Text::new(text.characterdata.data.clone(), &document); - NodeCast::from(&text) + let text: &JSRef<Text> = TextCast::to_ref(node).unwrap(); + let text = text.deref(); + let text = Text::new(text.characterdata.data.clone(), &*document); + NodeCast::from_unrooted(text) }, ProcessingInstructionNodeTypeId => { - let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(node).unwrap(); - let pi = pi.get(); + let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); + let pi = pi.deref(); let pi = ProcessingInstruction::new(pi.target.clone(), - pi.characterdata.data.clone(), &document); - NodeCast::from(&pi) + pi.characterdata.data.clone(), &*document); + NodeCast::from_unrooted(pi) }, - }; + }.root(); // Step 3. - if copy.is_document() { - document = DocumentCast::to(©).unwrap(); - } - assert!(copy.get().owner_doc() == &document); + let document = if copy.is_document() { + let doc: &JSRef<Document> = DocumentCast::to_ref(&*copy).unwrap(); + doc.unrooted().root() + } else { + document.unrooted().root() + }; + assert!(&*copy.owner_doc().root() == &*document); // Step 4 (some data already copied in step 2). match node.type_id() { DocumentNodeTypeId => { - let node_doc: JS<Document> = DocumentCast::to(node).unwrap(); - let node_doc = node_doc.get(); - let mut copy_doc: JS<Document> = DocumentCast::to(©).unwrap(); - let copy_doc = copy_doc.get_mut(); + let node_doc: &JSRef<Document> = DocumentCast::to_ref(node).unwrap(); + let copy_doc: &mut JSRef<Document> = DocumentCast::to_mut_ref(&mut *copy).unwrap(); copy_doc.set_encoding_name(node_doc.encoding_name.clone()); copy_doc.set_quirks_mode(node_doc.quirks_mode()); }, ElementNodeTypeId(..) => { - let node_elem: JS<Element> = ElementCast::to(node).unwrap(); - let node_elem = node_elem.get(); - let mut copy_elem: JS<Element> = ElementCast::to(©).unwrap(); + let node_elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let node_elem = node_elem.deref(); + let copy_elem: &mut JSRef<Element> = ElementCast::to_mut_ref(&mut *copy).unwrap(); // XXX: to avoid double borrowing compile error. we might be able to fix this after #1854 - let copy_elem_alias: JS<Element> = copy_elem.clone(); + let copy_elem_alias = copy_elem.clone(); - let copy_elem = copy_elem.get_mut(); + let copy_elem = copy_elem.deref_mut(); // FIXME: https://github.com/mozilla/servo/issues/1737 copy_elem.namespace = node_elem.namespace.clone(); - for attr in node_elem.attrs.iter() { - let attr = attr.get(); - copy_elem.attrs.push(Attr::new(&document.get().window, - attr.local_name.clone(), attr.value.clone(), - attr.name.clone(), attr.namespace.clone(), - attr.prefix.clone(), copy_elem_alias.clone())); + let window = document.deref().window.root(); + for attr in node_elem.attrs.iter().map(|attr| attr.root()) { + copy_elem.attrs.push_unrooted( + &Attr::new(&*window, + attr.deref().local_name.clone(), attr.deref().value.clone(), + attr.deref().name.clone(), attr.deref().namespace.clone(), + attr.deref().prefix.clone(), ©_elem_alias)); } }, _ => () @@ -1409,38 +1309,282 @@ impl Node { // Step 6. if clone_children == CloneChildren { - for ref child in node.get().children() { - let mut child_copy = Node::clone(child, Some(&document), clone_children); - let _inserted_node = Node::pre_insert(&mut child_copy, &mut copy, None); + for ref child in node.children() { + let mut child_copy = Node::clone(&*child, Some(&*document), clone_children).root(); + let _inserted_node = Node::pre_insert(&mut *child_copy, &mut *copy, None); } } // Step 7. - copy + Temporary::from_rooted(&*copy) } - // http://dom.spec.whatwg.org/#dom-node-insertbefore - pub fn InsertBefore(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>, child: Option<JS<Node>>) - -> Fallible<JS<Node>> { - Node::pre_insert(node, abstract_self, child) + /// Sends layout data, if any, back to the script task to be destroyed. + unsafe fn reap_layout_data(&mut self) { + if self.layout_data.is_present() { + let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new()); + let layout_chan = layout_data.take_chan(); + match layout_chan { + None => {} + Some(chan) => { + let LayoutChan(chan) = chan; + chan.send(ReapLayoutDataMsg(layout_data)) + }, + } + } + } +} + +pub trait NodeMethods { + fn NodeType(&self) -> u16; + fn NodeName(&self) -> DOMString; + fn GetBaseURI(&self) -> Option<DOMString>; + fn GetOwnerDocument(&self) -> Option<Temporary<Document>>; + fn GetParentNode(&self) -> Option<Temporary<Node>>; + fn GetParentElement(&self) -> Option<Temporary<Element>>; + fn HasChildNodes(&self) -> bool; + fn ChildNodes(&mut self) -> Temporary<NodeList>; + fn GetFirstChild(&self) -> Option<Temporary<Node>>; + fn GetLastChild(&self) -> Option<Temporary<Node>>; + fn GetPreviousSibling(&self) -> Option<Temporary<Node>>; + fn GetNextSibling(&self) -> Option<Temporary<Node>>; + fn GetNodeValue(&self) -> Option<DOMString>; + fn SetNodeValue(&mut self, val: Option<DOMString>) -> ErrorResult; + fn GetTextContent(&self) -> Option<DOMString>; + fn SetTextContent(&mut self, value: Option<DOMString>) -> ErrorResult; + fn InsertBefore(&mut self, node: &mut JSRef<Node>, child: Option<JSRef<Node>>) -> Fallible<Temporary<Node>>; + fn AppendChild(&mut self, node: &mut JSRef<Node>) -> Fallible<Temporary<Node>>; + fn ReplaceChild(&mut self, node: &mut JSRef<Node>, child: &mut JSRef<Node>) -> Fallible<Temporary<Node>>; + fn RemoveChild(&mut self, node: &mut JSRef<Node>) -> Fallible<Temporary<Node>>; + fn Normalize(&mut self); + fn CloneNode(&self, deep: bool) -> Temporary<Node>; + fn IsEqualNode(&self, maybe_node: Option<JSRef<Node>>) -> bool; + fn CompareDocumentPosition(&self, other: &JSRef<Node>) -> u16; + fn Contains(&self, maybe_other: Option<JSRef<Node>>) -> bool; + fn LookupPrefix(&self, _prefix: Option<DOMString>) -> Option<DOMString>; + fn LookupNamespaceURI(&self, _namespace: Option<DOMString>) -> Option<DOMString>; + fn IsDefaultNamespace(&self, _namespace: Option<DOMString>) -> bool; +} + +impl<'a> NodeMethods for JSRef<'a, Node> { + // http://dom.spec.whatwg.org/#dom-node-nodetype + fn NodeType(&self) -> u16 { + match self.type_id { + ElementNodeTypeId(_) => NodeConstants::ELEMENT_NODE, + TextNodeTypeId => NodeConstants::TEXT_NODE, + ProcessingInstructionNodeTypeId => NodeConstants::PROCESSING_INSTRUCTION_NODE, + CommentNodeTypeId => NodeConstants::COMMENT_NODE, + DocumentNodeTypeId => NodeConstants::DOCUMENT_NODE, + DoctypeNodeTypeId => NodeConstants::DOCUMENT_TYPE_NODE, + DocumentFragmentNodeTypeId => NodeConstants::DOCUMENT_FRAGMENT_NODE, + } + } + + // http://dom.spec.whatwg.org/#dom-node-nodename + fn NodeName(&self) -> DOMString { + match self.type_id { + ElementNodeTypeId(..) => { + let elem: &JSRef<Element> = ElementCast::to_ref(self).unwrap(); + elem.TagName() + } + TextNodeTypeId => ~"#text", + ProcessingInstructionNodeTypeId => { + let processing_instruction: &JSRef<ProcessingInstruction> = + ProcessingInstructionCast::to_ref(self).unwrap(); + processing_instruction.Target() + } + CommentNodeTypeId => ~"#comment", + DoctypeNodeTypeId => { + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(self).unwrap(); + doctype.deref().name.clone() + }, + DocumentFragmentNodeTypeId => ~"#document-fragment", + DocumentNodeTypeId => ~"#document" + } + } + + // http://dom.spec.whatwg.org/#dom-node-baseuri + fn GetBaseURI(&self) -> Option<DOMString> { + // FIXME (#1824) implement. + None + } + + // http://dom.spec.whatwg.org/#dom-node-ownerdocument + fn GetOwnerDocument(&self) -> Option<Temporary<Document>> { + match self.type_id { + ElementNodeTypeId(..) | + CommentNodeTypeId | + TextNodeTypeId | + ProcessingInstructionNodeTypeId | + DoctypeNodeTypeId | + DocumentFragmentNodeTypeId => Some(self.owner_doc()), + DocumentNodeTypeId => None + } + } + + // http://dom.spec.whatwg.org/#dom-node-parentnode + fn GetParentNode(&self) -> Option<Temporary<Node>> { + self.parent_node.clone().map(|node| Temporary::new(node)) + } + + // http://dom.spec.whatwg.org/#dom-node-parentelement + fn GetParentElement(&self) -> Option<Temporary<Element>> { + self.parent_node.clone() + .and_then(|parent| { + let parent = parent.root(); + ElementCast::to_ref(&*parent).map(|elem| { + Temporary::from_rooted(elem) + }) + }) + } + + // http://dom.spec.whatwg.org/#dom-node-haschildnodes + fn HasChildNodes(&self) -> bool { + self.first_child.is_some() + } + + // http://dom.spec.whatwg.org/#dom-node-childnodes + fn ChildNodes(&mut self) -> Temporary<NodeList> { + match self.child_list { + None => (), + Some(ref list) => return Temporary::new(list.clone()), + } + + let doc = self.owner_doc().root(); + let window = doc.deref().window.root(); + let child_list = NodeList::new_child_list(&*window, self); + self.child_list.assign(Some(child_list)); + Temporary::new(self.child_list.get_ref().clone()) + } + + // http://dom.spec.whatwg.org/#dom-node-firstchild + fn GetFirstChild(&self) -> Option<Temporary<Node>> { + self.first_child.clone().map(|node| Temporary::new(node)) + } + + // http://dom.spec.whatwg.org/#dom-node-lastchild + fn GetLastChild(&self) -> Option<Temporary<Node>> { + self.last_child.clone().map(|node| Temporary::new(node)) + } + + // http://dom.spec.whatwg.org/#dom-node-previoussibling + fn GetPreviousSibling(&self) -> Option<Temporary<Node>> { + self.prev_sibling.clone().map(|node| Temporary::new(node)) + } + + // http://dom.spec.whatwg.org/#dom-node-nextsibling + fn GetNextSibling(&self) -> Option<Temporary<Node>> { + self.next_sibling.clone().map(|node| Temporary::new(node)) + } + + // http://dom.spec.whatwg.org/#dom-node-nodevalue + fn GetNodeValue(&self) -> Option<DOMString> { + match self.type_id { + CommentNodeTypeId | + TextNodeTypeId | + ProcessingInstructionNodeTypeId => { + let chardata: &JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap(); + Some(chardata.Data()) + } + _ => { + None + } + } + } + + // http://dom.spec.whatwg.org/#dom-node-nodevalue + fn SetNodeValue(&mut self, val: Option<DOMString>) + -> ErrorResult { + match self.type_id { + CommentNodeTypeId | + TextNodeTypeId | + ProcessingInstructionNodeTypeId => { + self.SetTextContent(val) + } + _ => Ok(()) + } + } + + // http://dom.spec.whatwg.org/#dom-node-textcontent + fn GetTextContent(&self) -> Option<DOMString> { + match self.type_id { + DocumentFragmentNodeTypeId | + ElementNodeTypeId(..) => { + let mut content = ~""; + for node in self.traverse_preorder() { + if node.is_text() { + let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap(); + content.push_str(text.deref().characterdata.data.as_slice()); + } + } + Some(content) + } + CommentNodeTypeId | + TextNodeTypeId | + ProcessingInstructionNodeTypeId => { + let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap(); + Some(characterdata.Data()) + } + DoctypeNodeTypeId | + DocumentNodeTypeId => { + None + } + } } - pub fn wait_until_safe_to_modify_dom(&self) { - let document = self.owner_doc(); - document.get().wait_until_safe_to_modify_dom(); + // http://dom.spec.whatwg.org/#dom-node-textcontent + fn SetTextContent(&mut self, value: Option<DOMString>) + -> ErrorResult { + let value = null_str_as_empty(&value); + match self.type_id { + DocumentFragmentNodeTypeId | + ElementNodeTypeId(..) => { + // Step 1-2. + let node = if value.len() == 0 { + None + } else { + let document = self.owner_doc().root(); + Some(NodeCast::from_unrooted(document.deref().CreateTextNode(value))) + }.root(); + + // Step 3. + Node::replace_all(node.root_ref(), self); + } + CommentNodeTypeId | + TextNodeTypeId | + ProcessingInstructionNodeTypeId => { + self.wait_until_safe_to_modify_dom(); + + { + let characterdata: &mut JSRef<CharacterData> = CharacterDataCast::to_mut_ref(self).unwrap(); + characterdata.deref_mut().data = value.clone(); + } + + // Notify the document that the content of this node is different + let document = self.owner_doc().root(); + document.deref().content_changed(); + } + DoctypeNodeTypeId | + DocumentNodeTypeId => {} + } + Ok(()) + } + + // http://dom.spec.whatwg.org/#dom-node-insertbefore + fn InsertBefore(&mut self, node: &mut JSRef<Node>, child: Option<JSRef<Node>>) -> Fallible<Temporary<Node>> { + Node::pre_insert(node, self, child) } // http://dom.spec.whatwg.org/#dom-node-appendchild - pub fn AppendChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) - -> Fallible<JS<Node>> { - Node::pre_insert(node, abstract_self, None) + fn AppendChild(&mut self, node: &mut JSRef<Node>) -> Fallible<Temporary<Node>> { + Node::pre_insert(node, self, None) } // http://dom.spec.whatwg.org/#concept-node-replace - pub fn ReplaceChild(&self, parent: &mut JS<Node>, node: &mut JS<Node>, child: &mut JS<Node>) - -> Fallible<JS<Node>> { + fn ReplaceChild(&mut self, node: &mut JSRef<Node>, child: &mut JSRef<Node>) -> Fallible<Temporary<Node>> { + // Step 1. - match parent.type_id() { + match self.type_id() { DocumentNodeTypeId | DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => (), @@ -1448,19 +1592,19 @@ impl Node { } // Step 2. - if node.is_inclusive_ancestor_of(parent) { + if node.is_inclusive_ancestor_of(self) { return Err(HierarchyRequest); } // Step 3. - if !parent.is_parent_of(child) { + if !self.is_parent_of(child) { return Err(NotFound); } // Step 4-5. match node.type_id() { - TextNodeTypeId if parent.is_document() => return Err(HierarchyRequest), - DoctypeNodeTypeId if !parent.is_document() => return Err(HierarchyRequest), + TextNodeTypeId if self.is_document() => return Err(HierarchyRequest), + DoctypeNodeTypeId if !self.is_document() => return Err(HierarchyRequest), DocumentFragmentNodeTypeId | DoctypeNodeTypeId | ElementNodeTypeId(..) | @@ -1471,7 +1615,7 @@ impl Node { } // Step 6. - match parent.type_id() { + match self.type_id() { DocumentNodeTypeId => { match node.type_id() { // Step 6.1 @@ -1484,7 +1628,7 @@ impl Node { 0 => (), // Step 6.1.2 1 => { - if parent.child_elements().any(|c| &NodeCast::from(&c) != child) { + if self.child_elements().any(|c| NodeCast::from_ref(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1498,7 +1642,7 @@ impl Node { }, // Step 6.2 ElementNodeTypeId(..) => { - if parent.child_elements().any(|c| &NodeCast::from(&c) != child) { + if self.child_elements().any(|c| NodeCast::from_ref(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1508,10 +1652,10 @@ impl Node { }, // Step 6.3 DoctypeNodeTypeId => { - if parent.children().any(|c| c.is_doctype() && &c != child) { + if self.children().any(|c| c.is_doctype() && &c != child) { return Err(HierarchyRequest); } - if parent.children() + if self.children() .take_while(|c| c != child) .any(|c| c.is_element()) { return Err(HierarchyRequest); @@ -1528,25 +1672,26 @@ impl Node { // Ok if not caught by previous error checks. if *node == *child { - return Ok(child.clone()); + return Ok(Temporary::from_rooted(child)); } // Step 7-8. - let next_sibling = child.next_sibling(); + let next_sibling = child.next_sibling().map(|node| (*node.root()).clone()); let reference_child = match next_sibling { - Some(ref sibling) if sibling == node => node.next_sibling(), + Some(ref sibling) if sibling == node => node.next_sibling().map(|node| (*node.root()).clone()), _ => next_sibling }; // Step 9. - Node::adopt(node, &document_from_node(parent)); + let document = document_from_node(self).root(); + Node::adopt(node, &*document); { // Step 10. - Node::remove(child, parent, Suppressed); + Node::remove(child, self, Suppressed); // Step 11. - Node::insert(node, parent, reference_child, Suppressed); + Node::insert(node, self, reference_child, Suppressed); } // Step 12-14. @@ -1561,36 +1706,36 @@ impl Node { } // Step 15. - Ok(child.clone()) + Ok(Temporary::from_rooted(child)) } // http://dom.spec.whatwg.org/#dom-node-removechild - pub fn RemoveChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) - -> Fallible<JS<Node>> { - Node::pre_remove(node, abstract_self) + fn RemoveChild(&mut self, node: &mut JSRef<Node>) + -> Fallible<Temporary<Node>> { + Node::pre_remove(node, self) } // http://dom.spec.whatwg.org/#dom-node-normalize - pub fn Normalize(&mut self, abstract_self: &mut JS<Node>) { + fn Normalize(&mut self) { let mut prev_text = None; for mut child in self.children() { if child.is_text() { - let characterdata: JS<CharacterData> = CharacterDataCast::to(&child).unwrap(); - if characterdata.get().Length() == 0 { - abstract_self.remove_child(&mut child); + let mut child_alias = child.clone(); + let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(&child).unwrap(); + if characterdata.Length() == 0 { + self.remove_child(&mut child_alias); } else { match prev_text { - Some(ref text_node) => { - let mut prev_characterdata: JS<CharacterData> = CharacterDataCast::to(text_node).unwrap(); - let _ = prev_characterdata.get_mut().AppendData(characterdata.get().Data()); - abstract_self.remove_child(&mut child); + Some(ref mut text_node) => { + let prev_characterdata: &mut JSRef<CharacterData> = CharacterDataCast::to_mut_ref(text_node).unwrap(); + let _ = prev_characterdata.AppendData(characterdata.Data()); + self.remove_child(&mut child_alias); }, - None => prev_text = Some(child) + None => prev_text = Some(child_alias) } } } else { - let c = &mut child.clone(); - child.get_mut().Normalize(c); + child.Normalize(); prev_text = None; } @@ -1598,54 +1743,54 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-clonenode - pub fn CloneNode(&self, abstract_self: &mut JS<Node>, deep: bool) -> JS<Node> { + fn CloneNode(&self, deep: bool) -> Temporary<Node> { match deep { - true => Node::clone(abstract_self, None, CloneChildren), - false => Node::clone(abstract_self, None, DoNotCloneChildren) + true => Node::clone(self, None, CloneChildren), + false => Node::clone(self, None, DoNotCloneChildren) } } // http://dom.spec.whatwg.org/#dom-node-isequalnode - pub fn IsEqualNode(&self, abstract_self: &JS<Node>, maybe_node: Option<JS<Node>>) -> bool { - fn is_equal_doctype(node: &JS<Node>, other: &JS<Node>) -> bool { - let doctype: JS<DocumentType> = DocumentTypeCast::to(node).unwrap(); - let other_doctype: JS<DocumentType> = DocumentTypeCast::to(other).unwrap(); - (doctype.get().name == other_doctype.get().name) && - (doctype.get().public_id == other_doctype.get().public_id) && - (doctype.get().system_id == other_doctype.get().system_id) - } - fn is_equal_element(node: &JS<Node>, other: &JS<Node>) -> bool { - let element: JS<Element> = ElementCast::to(node).unwrap(); - let other_element: JS<Element> = ElementCast::to(other).unwrap(); + fn IsEqualNode(&self, maybe_node: Option<JSRef<Node>>) -> bool { + fn is_equal_doctype(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); + let other_doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(other).unwrap(); + (doctype.deref().name == other_doctype.deref().name) && + (doctype.deref().public_id == other_doctype.deref().public_id) && + (doctype.deref().system_id == other_doctype.deref().system_id) + } + fn is_equal_element(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap(); // FIXME: namespace prefix - (element.get().namespace == other_element.get().namespace) && - (element.get().local_name == other_element.get().local_name) && - (element.get().attrs.len() == other_element.get().attrs.len()) - } - fn is_equal_processinginstruction(node: &JS<Node>, other: &JS<Node>) -> bool { - let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(node).unwrap(); - let other_pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(other).unwrap(); - (pi.get().target == other_pi.get().target) && - (pi.get().characterdata.data == other_pi.get().characterdata.data) - } - fn is_equal_characterdata(node: &JS<Node>, other: &JS<Node>) -> bool { - let characterdata: JS<CharacterData> = CharacterDataCast::to(node).unwrap(); - let other_characterdata: JS<CharacterData> = CharacterDataCast::to(other).unwrap(); - characterdata.get().data == other_characterdata.get().data - } - fn is_equal_element_attrs(node: &JS<Node>, other: &JS<Node>) -> bool { - let element: JS<Element> = ElementCast::to(node).unwrap(); - let other_element: JS<Element> = ElementCast::to(other).unwrap(); - assert!(element.get().attrs.len() == other_element.get().attrs.len()); - element.get().attrs.iter().all(|attr| { - other_element.get().attrs.iter().any(|other_attr| { - (attr.get().namespace == other_attr.get().namespace) && - (attr.get().local_name == other_attr.get().local_name) && - (attr.get().value == other_attr.get().value) + (element.deref().namespace == other_element.deref().namespace) && + (element.deref().local_name == other_element.deref().local_name) && + (element.deref().attrs.len() == other_element.deref().attrs.len()) + } + fn is_equal_processinginstruction(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); + let other_pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(other).unwrap(); + (pi.deref().target == other_pi.deref().target) && + (pi.deref().characterdata.data == other_pi.deref().characterdata.data) + } + fn is_equal_characterdata(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(node).unwrap(); + let other_characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(other).unwrap(); + characterdata.deref().data == other_characterdata.deref().data + } + fn is_equal_element_attrs(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap(); + assert!(element.deref().attrs.len() == other_element.deref().attrs.len()); + element.deref().attrs.iter().map(|attr| attr.root()).all(|attr| { + other_element.deref().attrs.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) }) }) } - fn is_equal_node(this: &JS<Node>, node: &JS<Node>) -> bool { + fn is_equal_node(this: &JSRef<Node>, node: &JSRef<Node>) -> bool { // Step 2. if this.type_id() != node.type_id() { return false; @@ -1669,44 +1814,46 @@ impl Node { } // Step 6. - this.children().zip(node.children()).all(|(ref child, ref other_child)| is_equal_node(child, other_child)) + this.children().zip(node.children()).all(|(ref child, ref other_child)| { + is_equal_node(child, other_child) + }) } match maybe_node { // Step 1. None => false, // Step 2-6. - Some(ref node) => is_equal_node(abstract_self, node) + Some(ref node) => is_equal_node(self, node) } } // http://dom.spec.whatwg.org/#dom-node-comparedocumentposition - pub fn CompareDocumentPosition(&self, abstract_self: &JS<Node>, other: &JS<Node>) -> u16 { - if abstract_self == other { + fn CompareDocumentPosition(&self, other: &JSRef<Node>) -> u16 { + if self == other { // step 2. 0 } else { - let mut lastself = abstract_self.clone(); + let mut lastself = self.clone(); let mut lastother = other.clone(); - for ancestor in abstract_self.ancestors() { + for ancestor in self.ancestors() { if &ancestor == other { // step 4. return NodeConstants::DOCUMENT_POSITION_CONTAINS + NodeConstants::DOCUMENT_POSITION_PRECEDING; } - lastself = ancestor; + lastself = ancestor.clone(); } for ancestor in other.ancestors() { - if &ancestor == abstract_self { + if &ancestor == self { // step 5. return NodeConstants::DOCUMENT_POSITION_CONTAINED_BY + NodeConstants::DOCUMENT_POSITION_FOLLOWING; } - lastother = ancestor; + lastother = ancestor.clone(); } if lastself != lastother { - let abstract_uint: uintptr_t = as_uintptr(&abstract_self.get()); - let other_uint: uintptr_t = as_uintptr(&other.get()); + let abstract_uint: uintptr_t = as_uintptr(&*self); + let other_uint: uintptr_t = as_uintptr(&*other); let random = if abstract_uint < other_uint { NodeConstants::DOCUMENT_POSITION_FOLLOWING @@ -1724,7 +1871,7 @@ impl Node { // step 6. return NodeConstants::DOCUMENT_POSITION_PRECEDING; } - if &child == abstract_self { + if &child == self { // step 7. return NodeConstants::DOCUMENT_POSITION_FOLLOWING; } @@ -1734,103 +1881,33 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-contains - pub fn Contains(&self, abstract_self: &JS<Node>, maybe_other: Option<JS<Node>>) -> bool { + fn Contains(&self, maybe_other: Option<JSRef<Node>>) -> bool { match maybe_other { None => false, - Some(ref other) => abstract_self.is_inclusive_ancestor_of(other) + Some(ref other) => self.is_inclusive_ancestor_of(other) } } // http://dom.spec.whatwg.org/#dom-node-lookupprefix - pub fn LookupPrefix(&self, _prefix: Option<DOMString>) -> Option<DOMString> { + fn LookupPrefix(&self, _prefix: Option<DOMString>) -> Option<DOMString> { // FIXME (#1826) implement. None } // http://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri - pub fn LookupNamespaceURI(&self, _namespace: Option<DOMString>) -> Option<DOMString> { + fn LookupNamespaceURI(&self, _namespace: Option<DOMString>) -> Option<DOMString> { // FIXME (#1826) implement. None } // http://dom.spec.whatwg.org/#dom-node-isdefaultnamespace - pub fn IsDefaultNamespace(&self, _namespace: Option<DOMString>) -> bool { + fn IsDefaultNamespace(&self, _namespace: Option<DOMString>) -> bool { // FIXME (#1826) implement. false } - - // - // Low-level pointer stitching - // - - pub fn set_parent_node(&mut self, new_parent_node: Option<JS<Node>>) { - let doc = self.owner_doc().clone(); - doc.get().wait_until_safe_to_modify_dom(); - self.parent_node = new_parent_node - } - - pub fn set_first_child(&mut self, new_first_child: Option<JS<Node>>) { - let doc = self.owner_doc().clone(); - doc.get().wait_until_safe_to_modify_dom(); - self.first_child = new_first_child - } - - pub fn set_last_child(&mut self, new_last_child: Option<JS<Node>>) { - let doc = self.owner_doc().clone(); - doc.get().wait_until_safe_to_modify_dom(); - self.last_child = new_last_child - } - - pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<JS<Node>>) { - let doc = self.owner_doc().clone(); - doc.get().wait_until_safe_to_modify_dom(); - self.prev_sibling = new_prev_sibling - } - - pub fn set_next_sibling(&mut self, new_next_sibling: Option<JS<Node>>) { - let doc = self.owner_doc().clone(); - doc.get().wait_until_safe_to_modify_dom(); - self.next_sibling = new_next_sibling - } - - pub fn get_hover_state(&self) -> bool { - self.flags.get_in_hover_state() - } - - pub fn set_hover_state(&mut self, state: bool) { - self.flags.set_is_in_hover_state(state); - } - - #[inline] - pub fn parent_node_ref<'a>(&'a self) -> Option<&'a JS<Node>> { - self.parent_node.as_ref() - } - - #[inline] - pub fn first_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> { - self.first_child.as_ref() - } - - #[inline] - pub fn last_child_ref<'a>(&'a self) -> Option<&'a JS<Node>> { - self.last_child.as_ref() - } - - #[inline] - pub fn prev_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> { - self.prev_sibling.as_ref() - } - - #[inline] - pub fn next_sibling_ref<'a>(&'a self) -> Option<&'a JS<Node>> { - self.next_sibling.as_ref() - } - - pub unsafe fn get_hover_state_for_layout(&self) -> bool { - self.flags.get_in_hover_state() - } } + impl Reflectable for Node { fn reflector<'a>(&'a self) -> &'a Reflector { self.eventtarget.reflector() @@ -1841,19 +1918,19 @@ impl Reflectable for Node { } } -pub fn document_from_node<T: NodeBase>(derived: &JS<T>) -> JS<Document> { - let node: JS<Node> = NodeCast::from(derived); - node.get().owner_doc().clone() +pub fn document_from_node<T: NodeBase>(derived: &JSRef<T>) -> Temporary<Document> { + let node: &JSRef<Node> = NodeCast::from_ref(derived); + node.owner_doc() } -pub fn window_from_node<T: NodeBase>(derived: &JS<T>) -> JS<Window> { - let document: JS<Document> = document_from_node(derived); - document.get().window.clone() +pub fn window_from_node<T: NodeBase>(derived: &JSRef<T>) -> Temporary<Window> { + let document = document_from_node(derived).root(); + Temporary::new(document.deref().window.clone()) } -impl VirtualMethods for JS<Node> { - fn super_type(&self) -> Option<~VirtualMethods:> { - let eventtarget: JS<EventTarget> = EventTargetCast::from(self); - Some(~eventtarget as ~VirtualMethods:) +impl<'a> VirtualMethods for JSRef<'a, Node> { + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> { + let eventtarget: &mut JSRef<EventTarget> = EventTargetCast::from_mut_ref(self); + Some(eventtarget as &mut VirtualMethods:) } } diff --git a/src/components/script/dom/nodelist.rs b/src/components/script/dom/nodelist.rs index 714f0e34079..dc050b995ea 100644 --- a/src/components/script/dom/nodelist.rs +++ b/src/components/script/dom/nodelist.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::NodeListBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::node::{Node, NodeHelpers}; use dom::window::Window; @@ -22,45 +22,60 @@ pub struct NodeList { } impl NodeList { - pub fn new_inherited(window: JS<Window>, + pub fn new_inherited(window: &JSRef<Window>, list_type: NodeListType) -> NodeList { NodeList { list_type: list_type, reflector_: Reflector::new(), - window: window + window: window.unrooted() } } - pub fn new(window: &JS<Window>, - list_type: NodeListType) -> JS<NodeList> { - reflect_dom_object(~NodeList::new_inherited(window.clone(), list_type), + pub fn new(window: &JSRef<Window>, + list_type: NodeListType) -> Temporary<NodeList> { + reflect_dom_object(~NodeList::new_inherited(window, list_type), window, NodeListBinding::Wrap) } - pub fn new_simple_list(window: &JS<Window>, elements: Vec<JS<Node>>) -> JS<NodeList> { - NodeList::new(window, Simple(elements)) + pub fn new_simple_list(window: &JSRef<Window>, elements: Vec<JSRef<Node>>) -> Temporary<NodeList> { + NodeList::new(window, Simple(elements.iter().map(|element| element.unrooted()).collect())) } - pub fn new_child_list(window: &JS<Window>, node: &JS<Node>) -> JS<NodeList> { - NodeList::new(window, Children(node.clone())) + pub fn new_child_list(window: &JSRef<Window>, node: &JSRef<Node>) -> Temporary<NodeList> { + NodeList::new(window, Children(node.unrooted())) } +} + +pub trait NodeListMethods { + fn Length(&self) -> u32; + fn Item(&self, index: u32) -> Option<Temporary<Node>>; + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Node>>; +} - pub fn Length(&self) -> u32 { +impl<'a> NodeListMethods for JSRef<'a, NodeList> { + fn Length(&self) -> u32 { match self.list_type { Simple(ref elems) => elems.len() as u32, - Children(ref node) => node.children().len() as u32 + Children(ref node) => { + let node = node.root(); + node.deref().children().len() as u32 + } } } - pub fn Item(&self, index: u32) -> Option<JS<Node>> { + fn Item(&self, index: u32) -> Option<Temporary<Node>> { match self.list_type { _ if index >= self.Length() => None, - Simple(ref elems) => Some(elems.get(index as uint).clone()), - Children(ref node) => node.children().nth(index as uint) + Simple(ref elems) => Some(Temporary::new(elems.get(index as uint).clone())), + Children(ref node) => { + let node = node.root(); + node.deref().children().nth(index as uint) + .map(|child| Temporary::from_rooted(&child)) + } } } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Node>> { + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Temporary<Node>> { let item = self.Item(index); *found = item.is_some(); item diff --git a/src/components/script/dom/processinginstruction.rs b/src/components/script/dom/processinginstruction.rs index e39286d9aaa..2b7846b9f53 100644 --- a/src/components/script/dom/processinginstruction.rs +++ b/src/components/script/dom/processinginstruction.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::BindingDeclarations::ProcessingInstructionBinding; use dom::bindings::codegen::InheritTypes::ProcessingInstructionDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::characterdata::CharacterData; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -28,21 +28,25 @@ impl ProcessingInstructionDerived for EventTarget { } impl ProcessingInstruction { - pub fn new_inherited(target: DOMString, data: DOMString, document: JS<Document>) -> ProcessingInstruction { + pub fn new_inherited(target: DOMString, data: DOMString, document: &JSRef<Document>) -> ProcessingInstruction { ProcessingInstruction { characterdata: CharacterData::new_inherited(ProcessingInstructionNodeTypeId, data, document), target: target } } - pub fn new(target: DOMString, data: DOMString, document: &JS<Document>) -> JS<ProcessingInstruction> { - let node = ProcessingInstruction::new_inherited(target, data, document.clone()); + pub fn new(target: DOMString, data: DOMString, document: &JSRef<Document>) -> Temporary<ProcessingInstruction> { + let node = ProcessingInstruction::new_inherited(target, data, document); Node::reflect_node(~node, document, ProcessingInstructionBinding::Wrap) } } -impl ProcessingInstruction { - pub fn Target(&self) -> DOMString { +pub trait ProcessingInstructionMethods { + fn Target(&self) -> DOMString; +} + +impl<'a> ProcessingInstructionMethods for JSRef<'a, ProcessingInstruction> { + fn Target(&self) -> DOMString { self.target.clone() } } diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index 6283b5a350e..a860d1c3d0f 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -2,7 +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::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::codegen::BindingDeclarations::TestBindingBinding; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use self::TestBindingBinding::TestEnum; @@ -22,184 +22,370 @@ pub struct TestBinding { pub window: JS<Window>, } -impl TestBinding { - pub fn BooleanAttribute(&self) -> bool { false } - pub fn SetBooleanAttribute(&self, _: bool) {} - pub fn ByteAttribute(&self) -> i8 { 0 } - pub fn SetByteAttribute(&self, _: i8) {} - pub fn OctetAttribute(&self) -> u8 { 0 } - pub fn SetOctetAttribute(&self, _: u8) {} - pub fn ShortAttribute(&self) -> i16 { 0 } - pub fn SetShortAttribute(&self, _: i16) {} - pub fn UnsignedShortAttribute(&self) -> u16 { 0 } - pub fn SetUnsignedShortAttribute(&self, _: u16) {} - pub fn LongAttribute(&self) -> i32 { 0 } - pub fn SetLongAttribute(&self, _: i32) {} - pub fn UnsignedLongAttribute(&self) -> u32 { 0 } - pub fn SetUnsignedLongAttribute(&self, _: u32) {} - pub fn LongLongAttribute(&self) -> i64 { 0 } - pub fn SetLongLongAttribute(&self, _: i64) {} - pub fn UnsignedLongLongAttribute(&self) -> u64 { 0 } - pub fn SetUnsignedLongLongAttribute(&self, _: u64) {} - pub fn FloatAttribute(&self) -> f32 { 0. } - pub fn SetFloatAttribute(&self, _: f32) {} - pub fn DoubleAttribute(&self) -> f64 { 0. } - pub fn SetDoubleAttribute(&self, _: f64) {} - pub fn StringAttribute(&self) -> DOMString { ~"" } - pub fn SetStringAttribute(&self, _: DOMString) {} - pub fn ByteStringAttribute(&self) -> ByteString { ByteString::new(vec!()) } - pub fn SetByteStringAttribute(&self, _: ByteString) {} - pub fn EnumAttribute(&self) -> TestEnum { _empty } - pub fn SetEnumAttribute(&self, _: TestEnum) {} - pub fn InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) } - pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {} - pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() } - pub fn SetAnyAttribute(&self, _: *JSContext, _: JSVal) {} - - pub fn GetBooleanAttributeNullable(&self) -> Option<bool> { Some(false) } - pub fn SetBooleanAttributeNullable(&self, _: Option<bool>) {} - pub fn GetByteAttributeNullable(&self) -> Option<i8> { Some(0) } - pub fn SetByteAttributeNullable(&self, _: Option<i8>) {} - pub fn GetOctetAttributeNullable(&self) -> Option<u8> { Some(0) } - pub fn SetOctetAttributeNullable(&self, _: Option<u8>) {} - pub fn GetShortAttributeNullable(&self) -> Option<i16> { Some(0) } - pub fn SetShortAttributeNullable(&self, _: Option<i16>) {} - pub fn GetUnsignedShortAttributeNullable(&self) -> Option<u16> { Some(0) } - pub fn SetUnsignedShortAttributeNullable(&self, _: Option<u16>) {} - pub fn GetLongAttributeNullable(&self) -> Option<i32> { Some(0) } - pub fn SetLongAttributeNullable(&self, _: Option<i32>) {} - pub fn GetUnsignedLongAttributeNullable(&self) -> Option<u32> { Some(0) } - pub fn SetUnsignedLongAttributeNullable(&self, _: Option<u32>) {} - pub fn GetLongLongAttributeNullable(&self) -> Option<i64> { Some(0) } - pub fn SetLongLongAttributeNullable(&self, _: Option<i64>) {} - pub fn GetUnsignedLongLongAttributeNullable(&self) -> Option<u64> { Some(0) } - pub fn SetUnsignedLongLongAttributeNullable(&self, _: Option<u64>) {} - pub fn GetFloatAttributeNullable(&self) -> Option<f32> { Some(0.) } - pub fn SetFloatAttributeNullable(&self, _: Option<f32>) {} - pub fn GetDoubleAttributeNullable(&self) -> Option<f64> { Some(0.) } - pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {} - pub fn GetByteStringAttributeNullable(&self) -> Option<ByteString> { Some(ByteString::new(vec!())) } - pub fn SetByteStringAttributeNullable(&self, _: Option<ByteString>) {} - pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") } - pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {} - pub fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(_empty) } - pub fn GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> { Some(Blob::new(&self.window)) } - pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {} - - pub fn PassBoolean(&self, _: bool) {} - pub fn PassByte(&self, _: i8) {} - pub fn PassOctet(&self, _: u8) {} - pub fn PassShort(&self, _: i16) {} - pub fn PassUnsignedShort(&self, _: u16) {} - pub fn PassLong(&self, _: i32) {} - pub fn PassUnsignedLong(&self, _: u32) {} - pub fn PassLongLong(&self, _: i64) {} - pub fn PassUnsignedLongLong(&self, _: u64) {} - pub fn PassFloat(&self, _: f32) {} - pub fn PassDouble(&self, _: f64) {} - pub fn PassString(&self, _: DOMString) {} - pub fn PassByteString(&self, _: ByteString) {} - pub fn PassEnum(&self, _: TestEnum) {} - pub fn PassInterface(&self, _: &JS<Blob>) {} - pub fn PassUnion(&self, _: HTMLElementOrLong) {} - pub fn PassAny(&self, _: *JSContext, _: JSVal) {} - - pub fn PassNullableBoolean(&self, _: Option<bool>) {} - pub fn PassNullableByte(&self, _: Option<i8>) {} - pub fn PassNullableOctet(&self, _: Option<u8>) {} - pub fn PassNullableShort(&self, _: Option<i16>) {} - pub fn PassNullableUnsignedShort(&self, _: Option<u16>) {} - pub fn PassNullableLong(&self, _: Option<i32>) {} - pub fn PassNullableUnsignedLong(&self, _: Option<u32>) {} - pub fn PassNullableLongLong(&self, _: Option<i64>) {} - pub fn PassNullableUnsignedLongLong(&self, _: Option<u64>) {} - pub fn PassNullableFloat(&self, _: Option<f32>) {} - pub fn PassNullableDouble(&self, _: Option<f64>) {} - pub fn PassNullableString(&self, _: Option<DOMString>) {} - pub fn PassNullableByteString(&self, _: Option<ByteString>) {} - // pub fn PassNullableEnum(&self, _: Option<TestEnum>) {} - pub fn PassNullableInterface(&self, _: Option<JS<Blob>>) {} - pub fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} - pub fn PassNullableAny(&self, _: *JSContext, _: Option<JSVal>) {} - - pub fn PassOptionalBoolean(&self, _: Option<bool>) {} - pub fn PassOptionalByte(&self, _: Option<i8>) {} - pub fn PassOptionalOctet(&self, _: Option<u8>) {} - pub fn PassOptionalShort(&self, _: Option<i16>) {} - pub fn PassOptionalUnsignedShort(&self, _: Option<u16>) {} - pub fn PassOptionalLong(&self, _: Option<i32>) {} - pub fn PassOptionalUnsignedLong(&self, _: Option<u32>) {} - pub fn PassOptionalLongLong(&self, _: Option<i64>) {} - pub fn PassOptionalUnsignedLongLong(&self, _: Option<u64>) {} - pub fn PassOptionalFloat(&self, _: Option<f32>) {} - pub fn PassOptionalDouble(&self, _: Option<f64>) {} - pub fn PassOptionalString(&self, _: Option<DOMString>) {} - pub fn PassOptionalByteString(&self, _: Option<ByteString>) {} - pub fn PassOptionalEnum(&self, _: Option<TestEnum>) {} - pub fn PassOptionalInterface(&self, _: Option<JS<Blob>>) {} - pub fn PassOptionalUnion(&self, _: Option<HTMLElementOrLong>) {} - pub fn PassOptionalAny(&self, _: *JSContext, _: Option<JSVal>) {} - - pub fn PassOptionalNullableBoolean(&self, _: Option<Option<bool>>) {} - pub fn PassOptionalNullableByte(&self, _: Option<Option<i8>>) {} - pub fn PassOptionalNullableOctet(&self, _: Option<Option<u8>>) {} - pub fn PassOptionalNullableShort(&self, _: Option<Option<i16>>) {} - pub fn PassOptionalNullableUnsignedShort(&self, _: Option<Option<u16>>) {} - pub fn PassOptionalNullableLong(&self, _: Option<Option<i32>>) {} - pub fn PassOptionalNullableUnsignedLong(&self, _: Option<Option<u32>>) {} - pub fn PassOptionalNullableLongLong(&self, _: Option<Option<i64>>) {} - pub fn PassOptionalNullableUnsignedLongLong(&self, _: Option<Option<u64>>) {} - pub fn PassOptionalNullableFloat(&self, _: Option<Option<f32>>) {} - pub fn PassOptionalNullableDouble(&self, _: Option<Option<f64>>) {} - pub fn PassOptionalNullableString(&self, _: Option<Option<DOMString>>) {} - pub fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} - // pub fn PassOptionalNullableEnum(&self, _: Option<Option<TestEnum>>) {} - pub fn PassOptionalNullableInterface(&self, _: Option<Option<JS<Blob>>>) {} - pub fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>) {} - - pub fn PassOptionalBooleanWithDefault(&self, _: bool) {} - pub fn PassOptionalByteWithDefault(&self, _: i8) {} - pub fn PassOptionalOctetWithDefault(&self, _: u8) {} - pub fn PassOptionalShortWithDefault(&self, _: i16) {} - pub fn PassOptionalUnsignedShortWithDefault(&self, _: u16) {} - pub fn PassOptionalLongWithDefault(&self, _: i32) {} - pub fn PassOptionalUnsignedLongWithDefault(&self, _: u32) {} - pub fn PassOptionalLongLongWithDefault(&self, _: i64) {} - pub fn PassOptionalUnsignedLongLongWithDefault(&self, _: u64) {} - pub fn PassOptionalStringWithDefault(&self, _: DOMString) {} - pub fn PassOptionalEnumWithDefault(&self, _: TestEnum) {} - - pub fn PassOptionalNullableBooleanWithDefault(&self, _: Option<bool>) {} - pub fn PassOptionalNullableByteWithDefault(&self, _: Option<i8>) {} - pub fn PassOptionalNullableOctetWithDefault(&self, _: Option<u8>) {} - pub fn PassOptionalNullableShortWithDefault(&self, _: Option<i16>) {} - pub fn PassOptionalNullableUnsignedShortWithDefault(&self, _: Option<u16>) {} - pub fn PassOptionalNullableLongWithDefault(&self, _: Option<i32>) {} - pub fn PassOptionalNullableUnsignedLongWithDefault(&self, _: Option<u32>) {} - pub fn PassOptionalNullableLongLongWithDefault(&self, _: Option<i64>) {} - pub fn PassOptionalNullableUnsignedLongLongWithDefault(&self, _: Option<u64>) {} - pub fn PassOptionalNullableFloatWithDefault(&self, _: Option<f32>) {} - pub fn PassOptionalNullableDoubleWithDefault(&self, _: Option<f64>) {} - pub fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>) {} - pub fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} - // pub fn PassOptionalNullableEnumWithDefault(&self, _: Option<TestEnum>) {} - pub fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JS<Blob>>) {} - pub fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} - pub fn PassOptionalAnyWithDefault(&self, _: *JSContext, _: JSVal) {} - - pub fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>) {} - pub fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>) {} - pub fn PassOptionalNullableOctetWithNonNullDefault(&self, _: Option<u8>) {} - pub fn PassOptionalNullableShortWithNonNullDefault(&self, _: Option<i16>) {} - pub fn PassOptionalNullableUnsignedShortWithNonNullDefault(&self, _: Option<u16>) {} - pub fn PassOptionalNullableLongWithNonNullDefault(&self, _: Option<i32>) {} - pub fn PassOptionalNullableUnsignedLongWithNonNullDefault(&self, _: Option<u32>) {} - pub fn PassOptionalNullableLongLongWithNonNullDefault(&self, _: Option<i64>) {} - pub fn PassOptionalNullableUnsignedLongLongWithNonNullDefault(&self, _: Option<u64>) {} - // pub fn PassOptionalNullableFloatWithNonNullDefault(&self, _: Option<f32>) {} - // pub fn PassOptionalNullableDoubleWithNonNullDefault(&self, _: Option<f64>) {} - pub fn PassOptionalNullableStringWithNonNullDefault(&self, _: Option<DOMString>) {} - // pub fn PassOptionalNullableEnumWithNonNullDefault(&self, _: Option<TestEnum>) {} +pub trait TestBindingMethods { + fn BooleanAttribute(&self) -> bool; + fn SetBooleanAttribute(&self, _: bool); + fn ByteAttribute(&self) -> i8; + fn SetByteAttribute(&self, _: i8); + fn OctetAttribute(&self) -> u8; + fn SetOctetAttribute(&self, _: u8); + fn ShortAttribute(&self) -> i16; + fn SetShortAttribute(&self, _: i16); + fn UnsignedShortAttribute(&self) -> u16; + fn SetUnsignedShortAttribute(&self, _: u16); + fn LongAttribute(&self) -> i32; + fn SetLongAttribute(&self, _: i32); + fn UnsignedLongAttribute(&self) -> u32; + fn SetUnsignedLongAttribute(&self, _: u32); + fn LongLongAttribute(&self) -> i64; + fn SetLongLongAttribute(&self, _: i64); + fn UnsignedLongLongAttribute(&self) -> u64; + fn SetUnsignedLongLongAttribute(&self, _: u64); + fn FloatAttribute(&self) -> f32; + fn SetFloatAttribute(&self, _: f32); + fn DoubleAttribute(&self) -> f64; + fn SetDoubleAttribute(&self, _: f64); + fn StringAttribute(&self) -> DOMString; + fn SetStringAttribute(&self, _: DOMString); + fn ByteStringAttribute(&self) -> ByteString; + fn SetByteStringAttribute(&self, _: ByteString); + fn EnumAttribute(&self) -> TestEnum; + fn SetEnumAttribute(&self, _: TestEnum); + fn InterfaceAttribute(&self) -> Temporary<Blob>; + fn SetInterfaceAttribute(&self, _: &JSRef<Blob>); + fn AnyAttribute(&self, _: *JSContext) -> JSVal; + fn SetAnyAttribute(&self, _: *JSContext, _: JSVal); + + fn GetBooleanAttributeNullable(&self) -> Option<bool>; + fn SetBooleanAttributeNullable(&self, _: Option<bool>); + fn GetByteAttributeNullable(&self) -> Option<i8>; + fn SetByteAttributeNullable(&self, _: Option<i8>); + fn GetOctetAttributeNullable(&self) -> Option<u8>; + fn SetOctetAttributeNullable(&self, _: Option<u8>); + fn GetShortAttributeNullable(&self) -> Option<i16>; + fn SetShortAttributeNullable(&self, _: Option<i16>); + fn GetUnsignedShortAttributeNullable(&self) -> Option<u16>; + fn SetUnsignedShortAttributeNullable(&self, _: Option<u16>); + fn GetLongAttributeNullable(&self) -> Option<i32>; + fn SetLongAttributeNullable(&self, _: Option<i32>); + fn GetUnsignedLongAttributeNullable(&self) -> Option<u32>; + fn SetUnsignedLongAttributeNullable(&self, _: Option<u32>); + fn GetLongLongAttributeNullable(&self) -> Option<i64>; + fn SetLongLongAttributeNullable(&self, _: Option<i64>); + fn GetUnsignedLongLongAttributeNullable(&self) -> Option<u64>; + fn SetUnsignedLongLongAttributeNullable(&self, _: Option<u64>); + fn GetFloatAttributeNullable(&self) -> Option<f32>; + fn SetFloatAttributeNullable(&self, _: Option<f32>); + fn GetDoubleAttributeNullable(&self) -> Option<f64>; + fn SetDoubleAttributeNullable(&self, _: Option<f64>); + fn GetByteStringAttributeNullable(&self) -> Option<ByteString>; + fn SetByteStringAttributeNullable(&self, _: Option<ByteString>); + fn GetStringAttributeNullable(&self) -> Option<DOMString>; + fn SetStringAttributeNullable(&self, _: Option<DOMString>); + fn GetEnumAttributeNullable(&self) -> Option<TestEnum>; + fn GetInterfaceAttributeNullable(&self) -> Option<Temporary<Blob>>; + fn SetInterfaceAttributeNullable(&self, _: Option<JSRef<Blob>>); + + fn PassBoolean(&self, _: bool); + fn PassByte(&self, _: i8); + fn PassOctet(&self, _: u8); + fn PassShort(&self, _: i16); + fn PassUnsignedShort(&self, _: u16); + fn PassLong(&self, _: i32); + fn PassUnsignedLong(&self, _: u32); + fn PassLongLong(&self, _: i64); + fn PassUnsignedLongLong(&self, _: u64); + fn PassFloat(&self, _: f32); + fn PassDouble(&self, _: f64); + fn PassString(&self, _: DOMString); + fn PassByteString(&self, _: ByteString); + fn PassEnum(&self, _: TestEnum); + fn PassInterface(&self, _: &JSRef<Blob>); + fn PassUnion(&self, _: HTMLElementOrLong); + fn PassAny(&self, _: *JSContext, _: JSVal); + + fn PassNullableBoolean(&self, _: Option<bool>); + fn PassNullableByte(&self, _: Option<i8>); + fn PassNullableOctet(&self, _: Option<u8>); + fn PassNullableShort(&self, _: Option<i16>); + fn PassNullableUnsignedShort(&self, _: Option<u16>); + fn PassNullableLong(&self, _: Option<i32>); + fn PassNullableUnsignedLong(&self, _: Option<u32>); + fn PassNullableLongLong(&self, _: Option<i64>); + fn PassNullableUnsignedLongLong(&self, _: Option<u64>); + fn PassNullableFloat(&self, _: Option<f32>); + fn PassNullableDouble(&self, _: Option<f64>); + fn PassNullableString(&self, _: Option<DOMString>); + fn PassNullableByteString(&self, _: Option<ByteString>) {} + // fn PassNullableEnum(&self, _: Option<TestEnum>); + fn PassNullableInterface(&self, _: Option<JSRef<Blob>>); + fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>); + fn PassNullableAny(&self, _: *JSContext, _: Option<JSVal>); + + fn PassOptionalBoolean(&self, _: Option<bool>); + fn PassOptionalByte(&self, _: Option<i8>); + fn PassOptionalOctet(&self, _: Option<u8>); + fn PassOptionalShort(&self, _: Option<i16>); + fn PassOptionalUnsignedShort(&self, _: Option<u16>); + fn PassOptionalLong(&self, _: Option<i32>); + fn PassOptionalUnsignedLong(&self, _: Option<u32>); + fn PassOptionalLongLong(&self, _: Option<i64>); + fn PassOptionalUnsignedLongLong(&self, _: Option<u64>); + fn PassOptionalFloat(&self, _: Option<f32>); + fn PassOptionalDouble(&self, _: Option<f64>); + fn PassOptionalString(&self, _: Option<DOMString>); + fn PassOptionalByteString(&self, _: Option<ByteString>) {} + fn PassOptionalEnum(&self, _: Option<TestEnum>); + fn PassOptionalInterface(&self, _: Option<JSRef<Blob>>); + fn PassOptionalUnion(&self, _: Option<HTMLElementOrLong>); + fn PassOptionalAny(&self, _: *JSContext, _: Option<JSVal>); + + fn PassOptionalNullableBoolean(&self, _: Option<Option<bool>>); + fn PassOptionalNullableByte(&self, _: Option<Option<i8>>); + fn PassOptionalNullableOctet(&self, _: Option<Option<u8>>); + fn PassOptionalNullableShort(&self, _: Option<Option<i16>>); + fn PassOptionalNullableUnsignedShort(&self, _: Option<Option<u16>>); + fn PassOptionalNullableLong(&self, _: Option<Option<i32>>); + fn PassOptionalNullableUnsignedLong(&self, _: Option<Option<u32>>); + fn PassOptionalNullableLongLong(&self, _: Option<Option<i64>>); + fn PassOptionalNullableUnsignedLongLong(&self, _: Option<Option<u64>>); + fn PassOptionalNullableFloat(&self, _: Option<Option<f32>>); + fn PassOptionalNullableDouble(&self, _: Option<Option<f64>>); + fn PassOptionalNullableString(&self, _: Option<Option<DOMString>>); + fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} + // fn PassOptionalNullableEnum(&self, _: Option<Option<TestEnum>>); + fn PassOptionalNullableInterface(&self, _: Option<Option<JSRef<Blob>>>); + fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>); + + fn PassOptionalBooleanWithDefault(&self, _: bool); + fn PassOptionalByteWithDefault(&self, _: i8); + fn PassOptionalOctetWithDefault(&self, _: u8); + fn PassOptionalShortWithDefault(&self, _: i16); + fn PassOptionalUnsignedShortWithDefault(&self, _: u16); + fn PassOptionalLongWithDefault(&self, _: i32); + fn PassOptionalUnsignedLongWithDefault(&self, _: u32); + fn PassOptionalLongLongWithDefault(&self, _: i64); + fn PassOptionalUnsignedLongLongWithDefault(&self, _: u64); + fn PassOptionalStringWithDefault(&self, _: DOMString); + fn PassOptionalEnumWithDefault(&self, _: TestEnum); + + fn PassOptionalNullableBooleanWithDefault(&self, _: Option<bool>); + fn PassOptionalNullableByteWithDefault(&self, _: Option<i8>); + fn PassOptionalNullableOctetWithDefault(&self, _: Option<u8>); + fn PassOptionalNullableShortWithDefault(&self, _: Option<i16>); + fn PassOptionalNullableUnsignedShortWithDefault(&self, _: Option<u16>); + fn PassOptionalNullableLongWithDefault(&self, _: Option<i32>); + fn PassOptionalNullableUnsignedLongWithDefault(&self, _: Option<u32>); + fn PassOptionalNullableLongLongWithDefault(&self, _: Option<i64>); + fn PassOptionalNullableUnsignedLongLongWithDefault(&self, _: Option<u64>); + fn PassOptionalNullableFloatWithDefault(&self, _: Option<f32>); + fn PassOptionalNullableDoubleWithDefault(&self, _: Option<f64>); + fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>); + fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} + // fn PassOptionalNullableEnumWithDefault(&self, _: Option<TestEnum>); + fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JSRef<Blob>>); + fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>); + fn PassOptionalAnyWithDefault(&self, _: *JSContext, _: JSVal); + + fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>); + fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>); + fn PassOptionalNullableOctetWithNonNullDefault(&self, _: Option<u8>); + fn PassOptionalNullableShortWithNonNullDefault(&self, _: Option<i16>); + fn PassOptionalNullableUnsignedShortWithNonNullDefault(&self, _: Option<u16>); + fn PassOptionalNullableLongWithNonNullDefault(&self, _: Option<i32>); + fn PassOptionalNullableUnsignedLongWithNonNullDefault(&self, _: Option<u32>); + fn PassOptionalNullableLongLongWithNonNullDefault(&self, _: Option<i64>); + fn PassOptionalNullableUnsignedLongLongWithNonNullDefault(&self, _: Option<u64>); + // fn PassOptionalNullableFloatWithNonNullDefault(&self, _: Option<f32>); + // fn PassOptionalNullableDoubleWithNonNullDefault(&self, _: Option<f64>); + fn PassOptionalNullableStringWithNonNullDefault(&self, _: Option<DOMString>); + // fn PassOptionalNullableEnumWithNonNullDefault(&self, _: Option<TestEnum>); +} + +impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { + fn BooleanAttribute(&self) -> bool { false } + fn SetBooleanAttribute(&self, _: bool) {} + fn ByteAttribute(&self) -> i8 { 0 } + fn SetByteAttribute(&self, _: i8) {} + fn OctetAttribute(&self) -> u8 { 0 } + fn SetOctetAttribute(&self, _: u8) {} + fn ShortAttribute(&self) -> i16 { 0 } + fn SetShortAttribute(&self, _: i16) {} + fn UnsignedShortAttribute(&self) -> u16 { 0 } + fn SetUnsignedShortAttribute(&self, _: u16) {} + fn LongAttribute(&self) -> i32 { 0 } + fn SetLongAttribute(&self, _: i32) {} + fn UnsignedLongAttribute(&self) -> u32 { 0 } + fn SetUnsignedLongAttribute(&self, _: u32) {} + fn LongLongAttribute(&self) -> i64 { 0 } + fn SetLongLongAttribute(&self, _: i64) {} + fn UnsignedLongLongAttribute(&self) -> u64 { 0 } + fn SetUnsignedLongLongAttribute(&self, _: u64) {} + fn FloatAttribute(&self) -> f32 { 0. } + fn SetFloatAttribute(&self, _: f32) {} + fn DoubleAttribute(&self) -> f64 { 0. } + fn SetDoubleAttribute(&self, _: f64) {} + fn StringAttribute(&self) -> DOMString { ~"" } + fn SetStringAttribute(&self, _: DOMString) {} + fn ByteStringAttribute(&self) -> ByteString { ByteString::new(vec!()) } + fn SetByteStringAttribute(&self, _: ByteString) {} + fn EnumAttribute(&self) -> TestEnum { _empty } + fn SetEnumAttribute(&self, _: TestEnum) {} + fn InterfaceAttribute(&self) -> Temporary<Blob> { + let window = self.window.root(); + Blob::new(&*window) + } + fn SetInterfaceAttribute(&self, _: &JSRef<Blob>) {} + fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() } + fn SetAnyAttribute(&self, _: *JSContext, _: JSVal) {} + + fn GetBooleanAttributeNullable(&self) -> Option<bool> { Some(false) } + fn SetBooleanAttributeNullable(&self, _: Option<bool>) {} + fn GetByteAttributeNullable(&self) -> Option<i8> { Some(0) } + fn SetByteAttributeNullable(&self, _: Option<i8>) {} + fn GetOctetAttributeNullable(&self) -> Option<u8> { Some(0) } + fn SetOctetAttributeNullable(&self, _: Option<u8>) {} + fn GetShortAttributeNullable(&self) -> Option<i16> { Some(0) } + fn SetShortAttributeNullable(&self, _: Option<i16>) {} + fn GetUnsignedShortAttributeNullable(&self) -> Option<u16> { Some(0) } + fn SetUnsignedShortAttributeNullable(&self, _: Option<u16>) {} + fn GetLongAttributeNullable(&self) -> Option<i32> { Some(0) } + fn SetLongAttributeNullable(&self, _: Option<i32>) {} + fn GetUnsignedLongAttributeNullable(&self) -> Option<u32> { Some(0) } + fn SetUnsignedLongAttributeNullable(&self, _: Option<u32>) {} + fn GetLongLongAttributeNullable(&self) -> Option<i64> { Some(0) } + fn SetLongLongAttributeNullable(&self, _: Option<i64>) {} + fn GetUnsignedLongLongAttributeNullable(&self) -> Option<u64> { Some(0) } + fn SetUnsignedLongLongAttributeNullable(&self, _: Option<u64>) {} + fn GetFloatAttributeNullable(&self) -> Option<f32> { Some(0.) } + fn SetFloatAttributeNullable(&self, _: Option<f32>) {} + fn GetDoubleAttributeNullable(&self) -> Option<f64> { Some(0.) } + fn SetDoubleAttributeNullable(&self, _: Option<f64>) {} + fn GetByteStringAttributeNullable(&self) -> Option<ByteString> { Some(ByteString::new(vec!())) } + fn SetByteStringAttributeNullable(&self, _: Option<ByteString>) {} + fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") } + fn SetStringAttributeNullable(&self, _: Option<DOMString>) {} + fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(_empty) } + fn GetInterfaceAttributeNullable(&self) -> Option<Temporary<Blob>> { + let window = self.window.root(); + Some(Blob::new(&*window)) + } + fn SetInterfaceAttributeNullable(&self, _: Option<JSRef<Blob>>) {} + + fn PassBoolean(&self, _: bool) {} + fn PassByte(&self, _: i8) {} + fn PassOctet(&self, _: u8) {} + fn PassShort(&self, _: i16) {} + fn PassUnsignedShort(&self, _: u16) {} + fn PassLong(&self, _: i32) {} + fn PassUnsignedLong(&self, _: u32) {} + fn PassLongLong(&self, _: i64) {} + fn PassUnsignedLongLong(&self, _: u64) {} + fn PassFloat(&self, _: f32) {} + fn PassDouble(&self, _: f64) {} + fn PassString(&self, _: DOMString) {} + fn PassByteString(&self, _: ByteString) {} + fn PassEnum(&self, _: TestEnum) {} + fn PassInterface(&self, _: &JSRef<Blob>) {} + fn PassUnion(&self, _: HTMLElementOrLong) {} + fn PassAny(&self, _: *JSContext, _: JSVal) {} + + fn PassNullableBoolean(&self, _: Option<bool>) {} + fn PassNullableByte(&self, _: Option<i8>) {} + fn PassNullableOctet(&self, _: Option<u8>) {} + fn PassNullableShort(&self, _: Option<i16>) {} + fn PassNullableUnsignedShort(&self, _: Option<u16>) {} + fn PassNullableLong(&self, _: Option<i32>) {} + fn PassNullableUnsignedLong(&self, _: Option<u32>) {} + fn PassNullableLongLong(&self, _: Option<i64>) {} + fn PassNullableUnsignedLongLong(&self, _: Option<u64>) {} + fn PassNullableFloat(&self, _: Option<f32>) {} + fn PassNullableDouble(&self, _: Option<f64>) {} + fn PassNullableString(&self, _: Option<DOMString>) {} + fn PassNullableByteString(&self, _: Option<ByteString>) {} + // fn PassNullableEnum(&self, _: Option<TestEnum>) {} + fn PassNullableInterface(&self, _: Option<JSRef<Blob>>) {} + fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} + fn PassNullableAny(&self, _: *JSContext, _: Option<JSVal>) {} + + fn PassOptionalBoolean(&self, _: Option<bool>) {} + fn PassOptionalByte(&self, _: Option<i8>) {} + fn PassOptionalOctet(&self, _: Option<u8>) {} + fn PassOptionalShort(&self, _: Option<i16>) {} + fn PassOptionalUnsignedShort(&self, _: Option<u16>) {} + fn PassOptionalLong(&self, _: Option<i32>) {} + fn PassOptionalUnsignedLong(&self, _: Option<u32>) {} + fn PassOptionalLongLong(&self, _: Option<i64>) {} + fn PassOptionalUnsignedLongLong(&self, _: Option<u64>) {} + fn PassOptionalFloat(&self, _: Option<f32>) {} + fn PassOptionalDouble(&self, _: Option<f64>) {} + fn PassOptionalString(&self, _: Option<DOMString>) {} + fn PassOptionalByteString(&self, _: Option<ByteString>) {} + fn PassOptionalEnum(&self, _: Option<TestEnum>) {} + fn PassOptionalInterface(&self, _: Option<JSRef<Blob>>) {} + fn PassOptionalUnion(&self, _: Option<HTMLElementOrLong>) {} + fn PassOptionalAny(&self, _: *JSContext, _: Option<JSVal>) {} + + fn PassOptionalNullableBoolean(&self, _: Option<Option<bool>>) {} + fn PassOptionalNullableByte(&self, _: Option<Option<i8>>) {} + fn PassOptionalNullableOctet(&self, _: Option<Option<u8>>) {} + fn PassOptionalNullableShort(&self, _: Option<Option<i16>>) {} + fn PassOptionalNullableUnsignedShort(&self, _: Option<Option<u16>>) {} + fn PassOptionalNullableLong(&self, _: Option<Option<i32>>) {} + fn PassOptionalNullableUnsignedLong(&self, _: Option<Option<u32>>) {} + fn PassOptionalNullableLongLong(&self, _: Option<Option<i64>>) {} + fn PassOptionalNullableUnsignedLongLong(&self, _: Option<Option<u64>>) {} + fn PassOptionalNullableFloat(&self, _: Option<Option<f32>>) {} + fn PassOptionalNullableDouble(&self, _: Option<Option<f64>>) {} + fn PassOptionalNullableString(&self, _: Option<Option<DOMString>>) {} + fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} + // fn PassOptionalNullableEnum(&self, _: Option<Option<TestEnum>>) {} + fn PassOptionalNullableInterface(&self, _: Option<Option<JSRef<Blob>>>) {} + fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>) {} + + fn PassOptionalBooleanWithDefault(&self, _: bool) {} + fn PassOptionalByteWithDefault(&self, _: i8) {} + fn PassOptionalOctetWithDefault(&self, _: u8) {} + fn PassOptionalShortWithDefault(&self, _: i16) {} + fn PassOptionalUnsignedShortWithDefault(&self, _: u16) {} + fn PassOptionalLongWithDefault(&self, _: i32) {} + fn PassOptionalUnsignedLongWithDefault(&self, _: u32) {} + fn PassOptionalLongLongWithDefault(&self, _: i64) {} + fn PassOptionalUnsignedLongLongWithDefault(&self, _: u64) {} + fn PassOptionalStringWithDefault(&self, _: DOMString) {} + fn PassOptionalEnumWithDefault(&self, _: TestEnum) {} + + fn PassOptionalNullableBooleanWithDefault(&self, _: Option<bool>) {} + fn PassOptionalNullableByteWithDefault(&self, _: Option<i8>) {} + fn PassOptionalNullableOctetWithDefault(&self, _: Option<u8>) {} + fn PassOptionalNullableShortWithDefault(&self, _: Option<i16>) {} + fn PassOptionalNullableUnsignedShortWithDefault(&self, _: Option<u16>) {} + fn PassOptionalNullableLongWithDefault(&self, _: Option<i32>) {} + fn PassOptionalNullableUnsignedLongWithDefault(&self, _: Option<u32>) {} + fn PassOptionalNullableLongLongWithDefault(&self, _: Option<i64>) {} + fn PassOptionalNullableUnsignedLongLongWithDefault(&self, _: Option<u64>) {} + fn PassOptionalNullableFloatWithDefault(&self, _: Option<f32>) {} + fn PassOptionalNullableDoubleWithDefault(&self, _: Option<f64>) {} + fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>) {} + fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} + // fn PassOptionalNullableEnumWithDefault(&self, _: Option<TestEnum>) {} + fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JSRef<Blob>>) {} + fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} + fn PassOptionalAnyWithDefault(&self, _: *JSContext, _: JSVal) {} + + fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>) {} + fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>) {} + fn PassOptionalNullableOctetWithNonNullDefault(&self, _: Option<u8>) {} + fn PassOptionalNullableShortWithNonNullDefault(&self, _: Option<i16>) {} + fn PassOptionalNullableUnsignedShortWithNonNullDefault(&self, _: Option<u16>) {} + fn PassOptionalNullableLongWithNonNullDefault(&self, _: Option<i32>) {} + fn PassOptionalNullableUnsignedLongWithNonNullDefault(&self, _: Option<u32>) {} + fn PassOptionalNullableLongLongWithNonNullDefault(&self, _: Option<i64>) {} + fn PassOptionalNullableUnsignedLongLongWithNonNullDefault(&self, _: Option<u64>) {} + // fn PassOptionalNullableFloatWithNonNullDefault(&self, _: Option<f32>) {} + // fn PassOptionalNullableDoubleWithNonNullDefault(&self, _: Option<f64>) {} + fn PassOptionalNullableStringWithNonNullDefault(&self, _: Option<DOMString>) {} + // fn PassOptionalNullableEnumWithNonNullDefault(&self, _: Option<TestEnum>) {} } impl Reflectable for TestBinding { diff --git a/src/components/script/dom/text.rs b/src/components/script/dom/text.rs index 417ae255cb9..ac523808241 100644 --- a/src/components/script/dom/text.rs +++ b/src/components/script/dom/text.rs @@ -4,13 +4,13 @@ use dom::bindings::codegen::BindingDeclarations::TextBinding; use dom::bindings::codegen::InheritTypes::TextDerived; -use dom::bindings::js::JS; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::error::Fallible; use dom::characterdata::CharacterData; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::node::{Node, TextNodeTypeId}; -use dom::window::Window; +use dom::window::{Window, WindowMethods}; use servo_util::str::DOMString; /// An HTML text node. @@ -29,26 +29,34 @@ impl TextDerived for EventTarget { } impl Text { - pub fn new_inherited(text: DOMString, document: JS<Document>) -> Text { + pub fn new_inherited(text: DOMString, document: &JSRef<Document>) -> Text { Text { characterdata: CharacterData::new_inherited(TextNodeTypeId, text, document) } } - pub fn new(text: DOMString, document: &JS<Document>) -> JS<Text> { - let node = Text::new_inherited(text, document.clone()); + pub fn new(text: DOMString, document: &JSRef<Document>) -> Temporary<Text> { + let node = Text::new_inherited(text, document); Node::reflect_node(~node, document, TextBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, text: DOMString) -> Fallible<JS<Text>> { - Ok(Text::new(text.clone(), &owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>, text: DOMString) -> Fallible<Temporary<Text>> { + let document = owner.Document().root(); + Ok(Text::new(text.clone(), &*document)) } +} + +pub trait TextMethods { + fn SplitText(&self, _offset: u32) -> Fallible<Temporary<Text>>; + fn GetWholeText(&self) -> Fallible<DOMString>; +} - pub fn SplitText(&self, _offset: u32) -> Fallible<JS<Text>> { +impl<'a> TextMethods for JSRef<'a, Text> { + fn SplitText(&self, _offset: u32) -> Fallible<Temporary<Text>> { fail!("unimplemented") } - pub fn GetWholeText(&self) -> Fallible<DOMString> { + fn GetWholeText(&self) -> Fallible<DOMString> { Ok(~"") } } diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs index 7a2c94fb052..631353fe498 100644 --- a/src/components/script/dom/uievent.rs +++ b/src/components/script/dom/uievent.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::UIEventBinding; -use dom::bindings::codegen::InheritTypes::UIEventDerived; -use dom::bindings::js::JS; +use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived}; +use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable}; use dom::bindings::error::Fallible; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::event::{Event, EventTypeId, UIEventTypeId}; +use dom::event::{Event, EventMethods, EventTypeId, UIEventTypeId}; use dom::node::Node; use dom::window::Window; use servo_util::str::DOMString; @@ -36,85 +36,111 @@ impl UIEvent { } } - pub fn new(window: &JS<Window>) -> JS<UIEvent> { + pub fn new(window: &JSRef<Window>) -> Temporary<UIEvent> { reflect_dom_object(~UIEvent::new_inherited(UIEventTypeId), window, UIEventBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, + pub fn Constructor(owner: &JSRef<Window>, type_: DOMString, - init: &UIEventBinding::UIEventInit) -> Fallible<JS<UIEvent>> { - let mut ev = UIEvent::new(owner); - ev.get_mut().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, - init.view.clone(), init.detail); - Ok(ev) + init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> { + let mut ev = UIEvent::new(owner).root(); + ev.InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, + init.view.root_ref(), init.detail); + Ok(Temporary::from_rooted(&*ev)) } +} + +pub trait UIEventMethods { + fn GetView(&self) -> Option<Temporary<Window>>; + fn Detail(&self) -> i32; + fn LayerX(&self) -> i32; + fn LayerY(&self) -> i32; + fn PageX(&self) -> i32; + fn PageY(&self) -> i32; + fn Which(&self) -> u32; + fn GetRangeParent(&self) -> Option<Temporary<Node>>; + fn RangeOffset(&self) -> i32; + fn CancelBubble(&self) -> bool; + fn SetCancelBubble(&mut self, _val: bool); + fn IsChar(&self) -> bool; + fn InitUIEvent(&mut self, + type_: DOMString, + can_bubble: bool, + cancelable: bool, + view: Option<JSRef<Window>>, + detail: i32); +} - pub fn GetView(&self) -> Option<JS<Window>> { - self.view.clone() +impl<'a> UIEventMethods for JSRef<'a, UIEvent> { + fn GetView(&self) -> Option<Temporary<Window>> { + self.view.clone().map(|view| Temporary::new(view)) } - pub fn Detail(&self) -> i32 { + fn Detail(&self) -> i32 { self.detail } - pub fn InitUIEvent(&mut self, - type_: DOMString, - can_bubble: bool, - cancelable: bool, - view: Option<JS<Window>>, - detail: i32) { - self.event.InitEvent(type_, can_bubble, cancelable); - self.view = view; + fn InitUIEvent(&mut self, + type_: DOMString, + can_bubble: bool, + cancelable: bool, + view: Option<JSRef<Window>>, + detail: i32) { + { + let event: &mut JSRef<Event> = EventCast::from_mut_ref(self); + event.InitEvent(type_, can_bubble, cancelable); + } + self.view.assign(view); self.detail = detail; } - pub fn LayerX(&self) -> i32 { + fn LayerX(&self) -> i32 { //TODO 0 } - pub fn LayerY(&self) -> i32 { + fn LayerY(&self) -> i32 { //TODO 0 } - pub fn PageX(&self) -> i32 { + fn PageX(&self) -> i32 { //TODO 0 } - pub fn PageY(&self) -> i32 { + fn PageY(&self) -> i32 { //TODO 0 } - pub fn Which(&self) -> u32 { + fn Which(&self) -> u32 { //TODO 0 } - pub fn GetRangeParent(&self) -> Option<JS<Node>> { + fn GetRangeParent(&self) -> Option<Temporary<Node>> { //TODO None } - pub fn RangeOffset(&self) -> i32 { + fn RangeOffset(&self) -> i32 { //TODO 0 } - pub fn CancelBubble(&self) -> bool { + fn CancelBubble(&self) -> bool { //TODO false } - pub fn SetCancelBubble(&mut self, _val: bool) { + fn SetCancelBubble(&mut self, _val: bool) { //TODO } - pub fn IsChar(&self) -> bool { + fn IsChar(&self) -> bool { //TODO false } diff --git a/src/components/script/dom/validitystate.rs b/src/components/script/dom/validitystate.rs index 042d41a829a..15c654fc814 100644 --- a/src/components/script/dom/validitystate.rs +++ b/src/components/script/dom/validitystate.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::ValidityStateBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; @@ -15,55 +15,67 @@ pub struct ValidityState { } impl ValidityState { - pub fn new_inherited(window: JS<Window>) -> ValidityState { + pub fn new_inherited(window: &JSRef<Window>) -> ValidityState { ValidityState { reflector_: Reflector::new(), - window: window, + window: window.unrooted(), state: 0, } } - pub fn new(window: &JS<Window>) -> JS<ValidityState> { - reflect_dom_object(~ValidityState::new_inherited(window.clone()), + pub fn new(window: &JSRef<Window>) -> Temporary<ValidityState> { + reflect_dom_object(~ValidityState::new_inherited(window), window, ValidityStateBinding::Wrap) } } -impl ValidityState { - pub fn ValueMissing(&self) -> bool { +pub trait ValidityStateMethods { + fn ValueMissing(&self) -> bool; + fn TypeMismatch(&self) -> bool; + fn PatternMismatch(&self) -> bool; + fn TooLong(&self) -> bool; + fn RangeUnderflow(&self) -> bool; + fn RangeOverflow(&self) -> bool; + fn StepMismatch(&self) -> bool; + fn CustomError(&self) -> bool; + fn Valid(&self) -> bool; +} + +impl<'a> ValidityStateMethods for JSRef<'a, ValidityState> { + fn ValueMissing(&self) -> bool { false } - pub fn TypeMismatch(&self) -> bool { + fn TypeMismatch(&self) -> bool { false } - pub fn PatternMismatch(&self) -> bool { + fn PatternMismatch(&self) -> bool { false } - pub fn TooLong(&self) -> bool { + fn TooLong(&self) -> bool { false } - pub fn RangeUnderflow(&self) -> bool { + fn RangeUnderflow(&self) -> bool { false } - pub fn RangeOverflow(&self) -> bool { + fn RangeOverflow(&self) -> bool { false } - pub fn StepMismatch(&self) -> bool { + fn StepMismatch(&self) -> bool { false } - pub fn CustomError(&self) -> bool { + fn CustomError(&self) -> bool { false } - pub fn Valid(&self) -> bool { + fn Valid(&self) -> bool { true } } diff --git a/src/components/script/dom/virtualmethods.rs b/src/components/script/dom/virtualmethods.rs index 85ae37cb032..2b0d9aabfe5 100644 --- a/src/components/script/dom/virtualmethods.rs +++ b/src/components/script/dom/virtualmethods.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast; use dom::bindings::codegen::InheritTypes::HTMLImageElementCast; use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast; use dom::bindings::codegen::InheritTypes::HTMLStyleElementCast; -use dom::bindings::js::JS; +use dom::bindings::js::JSRef; use dom::element::Element; use dom::element::{ElementTypeId, HTMLImageElementTypeId}; use dom::element::{HTMLIFrameElementTypeId, HTMLObjectElementTypeId, HTMLStyleElementTypeId}; @@ -17,7 +17,7 @@ use dom::htmliframeelement::HTMLIFrameElement; use dom::htmlimageelement::HTMLImageElement; use dom::htmlobjectelement::HTMLObjectElement; use dom::htmlstyleelement::HTMLStyleElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, NodeHelpers, ElementNodeTypeId}; use servo_util::str::DOMString; /// Trait to allow DOM nodes to opt-in to overriding (or adding to) common @@ -25,7 +25,7 @@ use servo_util::str::DOMString; pub trait VirtualMethods { /// Returns self as the superclass of the implementation for this trait, /// if any. - fn super_type(&self) -> Option<~VirtualMethods:>; + fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:>; /// Called when changing or adding attributes, after the attribute's value /// has been updated. @@ -62,7 +62,7 @@ pub trait VirtualMethods { } /// Called on the parent when a node is added to its child list. - fn child_inserted(&mut self, child: &JS<Node>) { + fn child_inserted(&mut self, child: &JSRef<Node>) { match self.super_type() { Some(ref mut s) => s.child_inserted(child), _ => (), @@ -74,34 +74,34 @@ pub trait VirtualMethods { /// method call on the trait object will invoke the corresponding method on the /// concrete type, propagating up the parent hierarchy unless otherwise /// interrupted. -pub fn vtable_for<'a>(node: &JS<Node>) -> ~VirtualMethods: { - match node.get().type_id { +pub fn vtable_for<'a>(node: &'a mut JSRef<Node>) -> &'a mut VirtualMethods: { + match node.type_id() { ElementNodeTypeId(HTMLImageElementTypeId) => { - let element: JS<HTMLImageElement> = HTMLImageElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<HTMLImageElement> = HTMLImageElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } ElementNodeTypeId(HTMLIFrameElementTypeId) => { - let element: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<HTMLIFrameElement> = HTMLIFrameElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } ElementNodeTypeId(HTMLObjectElementTypeId) => { - let element: JS<HTMLObjectElement> = HTMLObjectElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<HTMLObjectElement> = HTMLObjectElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } ElementNodeTypeId(HTMLStyleElementTypeId) => { - let element: JS<HTMLStyleElement> = HTMLStyleElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<HTMLStyleElement> = HTMLStyleElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } ElementNodeTypeId(ElementTypeId) => { - let element: JS<Element> = ElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<Element> = ElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } ElementNodeTypeId(_) => { - let element: JS<HTMLElement> = HTMLElementCast::to(node).unwrap(); - ~element as ~VirtualMethods: + let element: &mut JSRef<HTMLElement> = HTMLElementCast::to_mut_ref(node).unwrap(); + element as &mut VirtualMethods: } _ => { - ~node.clone() as ~VirtualMethods: + node as &mut VirtualMethods: } } } diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index 1e4f7167f45..258a85b1455 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::WindowBinding; -use dom::bindings::js::JS; -use dom::bindings::trace::Untraceable; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable}; +use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::browsercontext::BrowserContext; use dom::document::Document; @@ -35,33 +35,25 @@ use std::rc::Rc; use serialize::{Encoder, Encodable}; use url::Url; -pub struct TimerHandle { - pub handle: i32, - pub cancel_chan: Option<Sender<()>>, -} +#[deriving(Eq, Encodable, TotalEq)] +pub struct TimerId(i32); -impl<S: Encoder<E>, E> Encodable<S, E> for TimerHandle { - fn encode(&self, _s: &mut S) -> Result<(), E> { - Ok(()) - } +#[deriving(Encodable)] +pub struct TimerHandle { + pub handle: TimerId, + pub data: TimerData, + pub cancel_chan: Untraceable<Option<Sender<()>>>, } -impl Hash for TimerHandle { +impl Hash for TimerId { fn hash(&self, state: &mut sip::SipState) { - self.handle.hash(state); + let TimerId(id) = *self; + id.hash(state); } } -impl Eq for TimerHandle { - fn eq(&self, other: &TimerHandle) -> bool { - self.handle == other.handle - } -} - -impl TotalEq for TimerHandle { } - impl TimerHandle { - fn cancel(&self) { + fn cancel(&mut self) { self.cancel_chan.as_ref().map(|chan| chan.send(())); } } @@ -74,7 +66,7 @@ pub struct Window { pub location: Option<JS<Location>>, pub navigator: Option<JS<Navigator>>, pub image_cache_task: ImageCacheTask, - pub active_timers: ~HashMap<i32, TimerHandle>, + pub active_timers: ~HashMap<TimerId, TimerHandle>, pub next_timer_handle: i32, pub compositor: Untraceable<~ScriptListener>, pub browser_context: Option<BrowserContext>, @@ -98,7 +90,7 @@ impl Window { #[unsafe_destructor] impl Drop for Window { fn drop(&mut self) { - for timer_handle in self.active_timers.values() { + for (_, timer_handle) in self.active_timers.mut_iter() { timer_handle.cancel(); } } @@ -107,94 +99,155 @@ impl Drop for Window { // Holder for the various JS values associated with setTimeout // (ie. function value to invoke and all arguments to pass // to the function when calling it) +#[deriving(Encodable)] pub struct TimerData { - pub handle: i32, pub is_interval: bool, - pub funval: JSVal, + pub funval: Traceable<JSVal>, } -impl Window { - pub fn Alert(&self, s: DOMString) { +pub trait WindowMethods { + fn Alert(&self, s: DOMString); + fn Close(&self); + fn Document(&self) -> Temporary<Document>; + fn Name(&self) -> DOMString; + fn SetName(&self, _name: DOMString); + fn Status(&self) -> DOMString; + fn SetStatus(&self, _status: DOMString); + fn Closed(&self) -> bool; + fn Stop(&self); + fn Focus(&self); + fn Blur(&self); + fn GetFrameElement(&self) -> Option<Temporary<Element>>; + fn Location(&mut self) -> Temporary<Location>; + fn Console(&mut self) -> Temporary<Console>; + fn Navigator(&mut self) -> Temporary<Navigator>; + fn Confirm(&self, _message: DOMString) -> bool; + fn Prompt(&self, _message: DOMString, _default: DOMString) -> Option<DOMString>; + fn Print(&self); + fn ShowModalDialog(&self, _cx: *JSContext, _url: DOMString, _argument: Option<JSVal>) -> JSVal; + fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32; + fn ClearTimeout(&mut self, handle: i32); + fn SetInterval(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32; + fn ClearInterval(&mut self, handle: i32); + fn Window(&self) -> Temporary<Window>; + fn Self(&self) -> Temporary<Window>; +} + +impl<'a> WindowMethods for JSRef<'a, Window> { + fn Alert(&self, s: DOMString) { // Right now, just print to the console println!("ALERT: {:s}", s); } - pub fn Close(&self) { + fn Close(&self) { let ScriptChan(ref chan) = self.script_chan; chan.send(ExitWindowMsg(self.page.id.clone())); } - pub fn Document(&self) -> JS<Document> { + fn Document(&self) -> Temporary<Document> { let frame = self.page().frame(); - frame.get_ref().document.clone() + Temporary::new(frame.get_ref().document.clone()) } - pub fn Name(&self) -> DOMString { + fn Name(&self) -> DOMString { ~"" } - pub fn SetName(&self, _name: DOMString) { + fn SetName(&self, _name: DOMString) { } - pub fn Status(&self) -> DOMString { + fn Status(&self) -> DOMString { ~"" } - pub fn SetStatus(&self, _status: DOMString) { + fn SetStatus(&self, _status: DOMString) { } - pub fn Closed(&self) -> bool { + fn Closed(&self) -> bool { false } - pub fn Stop(&self) { + fn Stop(&self) { } - pub fn Focus(&self) { + fn Focus(&self) { } - pub fn Blur(&self) { + fn Blur(&self) { } - pub fn GetFrameElement(&self) -> Option<JS<Element>> { + fn GetFrameElement(&self) -> Option<Temporary<Element>> { None } - pub fn Location(&mut self, abstract_self: &JS<Window>) -> JS<Location> { + fn Location(&mut self) -> Temporary<Location> { if self.location.is_none() { - self.location = Some(Location::new(abstract_self, self.page.clone())); + let page = self.deref().page.clone(); + let location = Location::new(self, page); + self.location.assign(Some(location)); } - self.location.get_ref().clone() + Temporary::new(self.location.get_ref().clone()) } - pub fn Console(&mut self, abstract_self: &JS<Window>) -> JS<Console> { + fn Console(&mut self) -> Temporary<Console> { if self.console.is_none() { - self.console = Some(Console::new(abstract_self)); + let console = Console::new(self); + self.console.assign(Some(console)); } - self.console.get_ref().clone() + Temporary::new(self.console.get_ref().clone()) } - pub fn Navigator(&mut self, abstract_self: &JS<Window>) -> JS<Navigator> { + fn Navigator(&mut self) -> Temporary<Navigator> { if self.navigator.is_none() { - self.navigator = Some(Navigator::new(abstract_self)); + let navigator = Navigator::new(self); + self.navigator.assign(Some(navigator)); } - self.navigator.get_ref().clone() + Temporary::new(self.navigator.get_ref().clone()) } - pub fn Confirm(&self, _message: DOMString) -> bool { + fn Confirm(&self, _message: DOMString) -> bool { false } - pub fn Prompt(&self, _message: DOMString, _default: DOMString) -> Option<DOMString> { + fn Prompt(&self, _message: DOMString, _default: DOMString) -> Option<DOMString> { None } - pub fn Print(&self) { + fn Print(&self) { } - pub fn ShowModalDialog(&self, _cx: *JSContext, _url: DOMString, _argument: Option<JSVal>) -> JSVal { + fn ShowModalDialog(&self, _cx: *JSContext, _url: DOMString, _argument: Option<JSVal>) -> JSVal { NullValue() } + + fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { + self.set_timeout_or_interval(callback, timeout, false) + } + + fn ClearTimeout(&mut self, handle: i32) { + let mut timer_handle = self.active_timers.pop(&TimerId(handle)); + match timer_handle { + Some(ref mut handle) => handle.cancel(), + None => { } + } + self.active_timers.remove(&TimerId(handle)); + } + + fn SetInterval(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { + self.set_timeout_or_interval(callback, timeout, true) + } + + fn ClearInterval(&mut self, handle: i32) { + self.ClearTimeout(handle); + } + + fn Window(&self) -> Temporary<Window> { + Temporary::from_rooted(self) + } + + fn Self(&self) -> Temporary<Window> { + self.Window() + } } impl Reflectable for Window { @@ -243,13 +296,8 @@ impl Window { let id = select.wait(); if id == timeout_handle.id() { timeout_port.recv(); - let data = ~TimerData { - handle: handle, - is_interval: is_interval, - funval: callback, - }; let ScriptChan(ref chan) = chan; - chan.send(FireTimerMsg(page_id, data)); + chan.send(FireTimerMsg(page_id, TimerId(handle))); if !is_interval { break; } @@ -258,38 +306,19 @@ impl Window { } } }); - self.active_timers.insert(handle, TimerHandle { handle: handle, cancel_chan: Some(cancel_chan) }); + let timer_id = TimerId(handle); + let timer = TimerHandle { + handle: timer_id, + cancel_chan: Untraceable::new(Some(cancel_chan)), + data: TimerData { + is_interval: is_interval, + funval: Traceable::new(callback), + } + }; + self.active_timers.insert(timer_id, timer); handle } - pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { - self.set_timeout_or_interval(callback, timeout, false) - } - - pub fn ClearTimeout(&mut self, handle: i32) { - let timer_handle = self.active_timers.pop(&handle); - match timer_handle { - Some(handle) => handle.cancel(), - None => { } - } - } - - pub fn SetInterval(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { - self.set_timeout_or_interval(callback, timeout, true) - } - - pub fn ClearInterval(&mut self, handle: i32) { - self.ClearTimeout(handle); - } - - pub fn Window(&self, abstract_self: &JS<Window>) -> JS<Window> { - abstract_self.clone() - } - - pub fn Self(&self, abstract_self: &JS<Window>) -> JS<Window> { - self.Window(abstract_self) - } - pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) { // FIXME This should probably be ReflowForQuery, not Display. All queries currently // currently rely on the display list, which means we can't destroy it by @@ -304,7 +333,7 @@ impl Window { self.page().join_layout(); } - pub fn init_browser_context(&mut self, doc: &JS<Document>) { + pub fn init_browser_context(&mut self, doc: &JSRef<Document>) { self.browser_context = Some(BrowserContext::new(doc)); } diff --git a/src/components/script/dom/xmlhttprequest.rs b/src/components/script/dom/xmlhttprequest.rs index 76099a4d0d0..5543f508315 100644 --- a/src/components/script/dom/xmlhttprequest.rs +++ b/src/components/script/dom/xmlhttprequest.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::InheritTypes::XMLHttpRequestDerived; use dom::document::Document; use dom::eventtarget::{EventTarget, XMLHttpRequestTargetTypeId}; use dom::bindings::error::Fallible; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable}; use js::jsapi::JSContext; use js::jsval::{JSVal, NullValue}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; @@ -31,7 +31,7 @@ pub struct XMLHttpRequest { ready_state: u16, timeout: u32, with_credentials: bool, - upload: JS<XMLHttpRequestUpload>, + upload: Option<JS<XMLHttpRequestUpload>>, response_url: DOMString, status: u16, status_text: ByteString, @@ -41,95 +41,126 @@ pub struct XMLHttpRequest { } impl XMLHttpRequest { - pub fn new_inherited(owner: &JS<Window>) -> XMLHttpRequest { - XMLHttpRequest { + pub fn new_inherited(owner: &JSRef<Window>) -> XMLHttpRequest { + let mut xhr = XMLHttpRequest { eventtarget: XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestTypeId), ready_state: 0, timeout: 0u32, with_credentials: false, - upload: XMLHttpRequestUpload::new(owner), + upload: None, response_url: ~"", status: 0, status_text: ByteString::new(vec!()), response_type: _empty, response_text: ~"", response_xml: None - } + }; + xhr.upload.assign(Some(XMLHttpRequestUpload::new(owner))); + xhr } - pub fn new(window: &JS<Window>) -> JS<XMLHttpRequest> { + pub fn new(window: &JSRef<Window>) -> Temporary<XMLHttpRequest> { reflect_dom_object(~XMLHttpRequest::new_inherited(window), window, XMLHttpRequestBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<XMLHttpRequest>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Temporary<XMLHttpRequest>> { Ok(XMLHttpRequest::new(owner)) } - pub fn ReadyState(&self) -> u16 { +} + +pub trait XMLHttpRequestMethods { + fn ReadyState(&self) -> u16; + fn Open(&self, _method: ByteString, _url: DOMString); + fn Open_(&self, _method: ByteString, _url: DOMString, _async: bool, + _username: Option<DOMString>, _password: Option<DOMString>); + fn SetRequestHeader(&self, _name: ByteString, _value: ByteString); + fn Timeout(&self) -> u32; + fn SetTimeout(&mut self, timeout: u32); + fn WithCredentials(&self) -> bool; + fn SetWithCredentials(&mut self, with_credentials: bool); + fn Upload(&self) -> Temporary<XMLHttpRequestUpload>; + fn Send(&self, _data: Option<DOMString>); + fn Abort(&self); + fn ResponseURL(&self) -> DOMString; + fn Status(&self) -> u16; + fn StatusText(&self) -> ByteString; + fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString>; + fn GetAllResponseHeaders(&self) -> ByteString; + fn OverrideMimeType(&self, _mime: DOMString); + fn ResponseType(&self) -> XMLHttpRequestResponseType; + fn SetResponseType(&mut self, response_type: XMLHttpRequestResponseType); + fn Response(&self, _cx: *JSContext) -> JSVal; + fn ResponseText(&self) -> DOMString; + fn GetResponseXML(&self) -> Option<Temporary<Document>>; +} + +impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { + fn ReadyState(&self) -> u16 { self.ready_state } - pub fn Open(&self, _method: ByteString, _url: DOMString) { + fn Open(&self, _method: ByteString, _url: DOMString) { } - pub fn Open_(&self, _method: ByteString, _url: DOMString, _async: bool, + fn Open_(&self, _method: ByteString, _url: DOMString, _async: bool, _username: Option<DOMString>, _password: Option<DOMString>) { } - pub fn SetRequestHeader(&self, _name: ByteString, _value: ByteString) { + fn SetRequestHeader(&self, _name: ByteString, _value: ByteString) { } - pub fn Timeout(&self) -> u32 { + fn Timeout(&self) -> u32 { self.timeout } - pub fn SetTimeout(&mut self, timeout: u32) { + fn SetTimeout(&mut self, timeout: u32) { self.timeout = timeout } - pub fn WithCredentials(&self) -> bool { + fn WithCredentials(&self) -> bool { self.with_credentials } - pub fn SetWithCredentials(&mut self, with_credentials: bool) { + fn SetWithCredentials(&mut self, with_credentials: bool) { self.with_credentials = with_credentials } - pub fn Upload(&self) -> JS<XMLHttpRequestUpload> { - self.upload.clone() + fn Upload(&self) -> Temporary<XMLHttpRequestUpload> { + Temporary::new(self.upload.get_ref().clone()) } - pub fn Send(&self, _data: Option<DOMString>) { + fn Send(&self, _data: Option<DOMString>) { } - pub fn Abort(&self) { + fn Abort(&self) { } - pub fn ResponseURL(&self) -> DOMString { + fn ResponseURL(&self) -> DOMString { self.response_url.clone() } - pub fn Status(&self) -> u16 { + fn Status(&self) -> u16 { self.status } - pub fn StatusText(&self) -> ByteString { + fn StatusText(&self) -> ByteString { self.status_text.clone() } - pub fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString> { + fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString> { None } - pub fn GetAllResponseHeaders(&self) -> ByteString { + fn GetAllResponseHeaders(&self) -> ByteString { ByteString::new(vec!()) } - pub fn OverrideMimeType(&self, _mime: DOMString) { + fn OverrideMimeType(&self, _mime: DOMString) { } - pub fn ResponseType(&self) -> XMLHttpRequestResponseType { + fn ResponseType(&self) -> XMLHttpRequestResponseType { self.response_type } - pub fn SetResponseType(&mut self, response_type: XMLHttpRequestResponseType) { + fn SetResponseType(&mut self, response_type: XMLHttpRequestResponseType) { self.response_type = response_type } - pub fn Response(&self, _cx: *JSContext) -> JSVal { + fn Response(&self, _cx: *JSContext) -> JSVal { NullValue() } - pub fn ResponseText(&self) -> DOMString { + fn ResponseText(&self) -> DOMString { self.response_text.clone() } - pub fn GetResponseXML(&self) -> Option<JS<Document>> { - self.response_xml.clone() + fn GetResponseXML(&self) -> Option<Temporary<Document>> { + self.response_xml.clone().map(|response| Temporary::new(response)) } } diff --git a/src/components/script/dom/xmlhttprequesteventtarget.rs b/src/components/script/dom/xmlhttprequesteventtarget.rs index 55708581a1d..68d67fab89b 100644 --- a/src/components/script/dom/xmlhttprequesteventtarget.rs +++ b/src/components/script/dom/xmlhttprequesteventtarget.rs @@ -37,4 +37,7 @@ impl Reflectable for XMLHttpRequestEventTarget { fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { self.eventtarget.mut_reflector() } +} + +pub trait XMLHttpRequestEventTargetMethods { }
\ No newline at end of file diff --git a/src/components/script/dom/xmlhttprequestupload.rs b/src/components/script/dom/xmlhttprequestupload.rs index bcfb2d02c47..6f373ab0a65 100644 --- a/src/components/script/dom/xmlhttprequestupload.rs +++ b/src/components/script/dom/xmlhttprequestupload.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::InheritTypes::XMLHttpRequestUploadDerived; use dom::bindings::codegen::BindingDeclarations::XMLHttpRequestUploadBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{Temporary, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::eventtarget::{EventTarget, XMLHttpRequestTargetTypeId}; use dom::window::Window; @@ -22,7 +22,7 @@ impl XMLHttpRequestUpload { eventtarget:XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestUploadTypeId) } } - pub fn new(window: &JS<Window>) -> JS<XMLHttpRequestUpload> { + pub fn new(window: &JSRef<Window>) -> Temporary<XMLHttpRequestUpload> { reflect_dom_object(~XMLHttpRequestUpload::new_inherited(), window, XMLHttpRequestUploadBinding::Wrap) @@ -45,4 +45,7 @@ impl XMLHttpRequestUploadDerived for EventTarget { _ => false } } +} + +pub trait XMLHttpRequestUploadMethods { }
\ No newline at end of file diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index 18945f9062a..8cebc7326e6 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -2,17 +2,18 @@ * 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::AttrMethods; use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, TextCast, ElementCast}; use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Root}; use dom::bindings::utils::Reflectable; -use dom::document::Document; +use dom::document::{Document, DocumentHelpers}; use dom::element::{AttributeHandlers, HTMLLinkElementTypeId, HTMLIFrameElementTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6}; -use dom::htmliframeelement::IFrameSize; +use dom::htmliframeelement::{IFrameSize, HTMLIFrameElementHelpers}; use dom::htmlformelement::HTMLFormElement; -use dom::node::{ElementNodeTypeId, INode, NodeHelpers}; +use dom::node::{ElementNodeTypeId, NodeHelpers, NodeMethods}; use dom::types::*; use html::cssparse::{StylesheetProvenance, UrlProvenance, spawn_css_parser}; use script_task::Page; @@ -39,7 +40,7 @@ macro_rules! handle_element( $ctor: ident $(, $arg:expr )*) => ( if $string == $localName { - return ElementCast::from(&$ctor::new($localName, $document $(, $arg)*)); + return ElementCast::from_unrooted($ctor::new($localName, $document $(, $arg)*)); } ) ) @@ -74,20 +75,20 @@ pub struct HtmlParserResult { pub discovery_port: Receiver<HtmlDiscoveryMessage>, } -trait NodeWrapping { +trait NodeWrapping<T> { unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr; - unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self; } -impl<T: NodeBase+Reflectable> NodeWrapping for JS<T> { +impl<'a, T: NodeBase+Reflectable> NodeWrapping<T> for JSRef<'a, T> { unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr { - cast::transmute(self.get()) - } - unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> JS<T> { - JS::from_raw(cast::transmute(n)) + cast::transmute(self.deref()) } } +unsafe fn from_hubbub_node<T: Reflectable>(n: hubbub::NodeDataPtr) -> Temporary<T> { + Temporary::new(JS::from_raw(cast::transmute(n))) +} + /** Runs a task that coordinates parsing links to css stylesheets. @@ -160,7 +161,7 @@ fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>, // Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized // via atomization (issue #85). -pub fn build_element_from_tag(tag: DOMString, document: &JS<Document>) -> JS<Element> { +pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> Temporary<Element> { // TODO (Issue #85): use atoms handle_element!(document, tag, "a", HTMLAnchorElement); handle_element!(document, tag, "applet", HTMLAppletElement); @@ -242,11 +243,11 @@ pub fn build_element_from_tag(tag: DOMString, document: &JS<Document>) -> JS<Ele handle_element!(document, tag, "ul", HTMLUListElement); handle_element!(document, tag, "video", HTMLVideoElement); - return ElementCast::from(&HTMLUnknownElement::new(tag, document)); + return ElementCast::from_unrooted(HTMLUnknownElement::new(tag, document)); } pub fn parse_html(page: &Page, - document: &mut JS<Document>, + document: &mut JSRef<Document>, url: Url, resource_task: ResourceTask) -> HtmlParserResult { @@ -308,8 +309,9 @@ pub fn parse_html(page: &Page, // NOTE: tmp vars are workaround for lifetime issues. Both required. let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; - let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp)); - unsafe { comment.to_hubbub_node() } + let comment = Comment::new(data, *tmp).root(); + let comment: &JSRef<Node> = NodeCast::from_ref(&*comment); + unsafe { comment.to_hubbub_node() } }, create_doctype: |doctype: ~hubbub::Doctype| { debug!("create doctype"); @@ -320,17 +322,17 @@ pub fn parse_html(page: &Page, // NOTE: tmp vars are workaround for lifetime issues. Both required. let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; - let doctype_node = DocumentType::new(name, public_id, system_id, *tmp); + let doctype_node = DocumentType::new(name, public_id, system_id, *tmp).root(); unsafe { - doctype_node.to_hubbub_node() + doctype_node.deref().to_hubbub_node() } }, create_element: |tag: ~hubbub::Tag| { - debug!("create element"); + debug!("create element {:?}", tag.name.clone()); // NOTE: tmp vars are workaround for lifetime issues. Both required. let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; - let mut element = build_element_from_tag(tag.name.clone(), *tmp); + let mut element = build_element_from_tag(tag.name.clone(), *tmp).root(); debug!("-- attach attrs"); for attr in tag.attributes.iter() { @@ -340,21 +342,36 @@ pub fn parse_html(page: &Page, attr.value.clone()).is_ok()); } + //FIXME: workaround for https://github.com/mozilla/rust/issues/13246; + // we get unrooting order failures if these are inside the match. + let rel = { + let rel = element.get_attribute(Null, "rel").root(); + rel.map(|a| a.deref().Value()) + }; + let href = { + let href= element.get_attribute(Null, "href").root(); + href.map(|a| a.deref().Value()) + }; + let src_opt = { + let src_opt = element.get_attribute(Null, "src").root(); + src_opt.map(|a| a.deref().Value()) + }; + // Spawn additional parsing, network loads, etc. from tag and attrs - match element.get().node.type_id { + let type_id = { + let node: &JSRef<Node> = NodeCast::from_ref(&*element); + node.type_id() + }; + match type_id { // Handle CSS style sheets from <link> elements ElementNodeTypeId(HTMLLinkElementTypeId) => { - match (element.get_attribute(Null, "rel"), - element.get_attribute(Null, "href")) { - (Some(ref rel), Some(ref href)) if rel.get() - .value_ref() - .split(HTML_SPACE_CHARACTERS. - as_slice()) + match (rel, href) { + (Some(ref rel), Some(ref href)) if rel.split(HTML_SPACE_CHARACTERS.as_slice()) .any(|s| { s.eq_ignore_ascii_case("stylesheet") }) => { - debug!("found CSS stylesheet: {:s}", href.get().value_ref()); - let url = parse_url(href.get().value_ref(), Some(url2.clone())); + debug!("found CSS stylesheet: {:s}", *href); + let url = parse_url(href.as_slice(), Some(url2.clone())); css_chan2.send(CSSTaskNewFile(UrlProvenance(url, resource_task.clone()))); } _ => {} @@ -363,21 +380,19 @@ pub fn parse_html(page: &Page, ElementNodeTypeId(HTMLIFrameElementTypeId) => { let iframe_chan = discovery_chan.clone(); - let mut iframe_element: JS<HTMLIFrameElement> = - HTMLIFrameElementCast::to(&element).unwrap(); - let sandboxed = iframe_element.get().is_sandboxed(); - let elem: JS<Element> = ElementCast::from(&iframe_element); - let src_opt = elem.get_attribute(Null, "src").map(|x| x.get().Value()); + let iframe_element: &mut JSRef<HTMLIFrameElement> = + HTMLIFrameElementCast::to_mut_ref(&mut *element).unwrap(); + let sandboxed = iframe_element.is_sandboxed(); for src in src_opt.iter() { let iframe_url = parse_url(*src, Some(url2.clone())); - iframe_element.get_mut().set_frame(iframe_url.clone()); + iframe_element.set_frame(iframe_url.clone()); // Subpage Id let subpage_id = *next_subpage_id.borrow(); let SubpageId(id_num) = subpage_id; *next_subpage_id.borrow_mut() = SubpageId(id_num + 1); - iframe_element.get_mut().size = Some(IFrameSize { + iframe_element.deref_mut().size = Some(IFrameSize { pipeline_id: pipeline_id, subpage_id: subpage_id, }); @@ -396,17 +411,17 @@ pub fn parse_html(page: &Page, // NOTE: tmp vars are workaround for lifetime issues. Both required. let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; - let text = Text::new(data, *tmp); - unsafe { text.to_hubbub_node() } + let text = Text::new(data, *tmp).root(); + unsafe { text.deref().to_hubbub_node() } }, ref_node: |_| {}, unref_node: |_| {}, append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| { unsafe { debug!("append child {:x} {:x}", parent, child); - let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent); - let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child); - assert!(parent.AppendChild(&mut child).is_ok()); + let mut child = from_hubbub_node(child).root(); + let mut parent: Root<Node> = from_hubbub_node(parent).root(); + assert!(parent.AppendChild(&mut *child).is_ok()); } child }, @@ -446,32 +461,32 @@ pub fn parse_html(page: &Page, // NOTE: tmp vars are workaround for lifetime issues. Both required. let mut tmp_borrow = doc_cell.borrow_mut(); let tmp = &mut *tmp_borrow; - tmp.get_mut().set_quirks_mode(mode); + tmp.set_quirks_mode(mode); }, encoding_change: |encname| { debug!("encoding change"); // NOTE: tmp vars are workaround for lifetime issues. Both required. let mut tmp_borrow = doc_cell.borrow_mut(); let tmp = &mut *tmp_borrow; - tmp.get_mut().set_encoding_name(encname); + tmp.set_encoding_name(encname); }, complete_script: |script| { unsafe { - let script: JS<Element> = NodeWrapping::from_hubbub_node(script); - match script.get_attribute(Null, "src") { + let script: &JSRef<Element> = &*from_hubbub_node(script).root(); + match script.get_attribute(Null, "src").root() { Some(src) => { - debug!("found script: {:s}", src.get().Value()); - let new_url = parse_url(src.get().value_ref(), Some(url3.clone())); + debug!("found script: {:s}", src.deref().Value()); + let new_url = parse_url(src.deref().value_ref(), Some(url3.clone())); js_chan2.send(JSTaskNewFile(new_url)); } None => { let mut data = vec!(); - let scriptnode: JS<Node> = NodeCast::from(&script); + let scriptnode: &JSRef<Node> = NodeCast::from_ref(script); debug!("iterating over children {:?}", scriptnode.first_child()); for child in scriptnode.children() { debug!("child = {:?}", child); - let text: JS<Text> = TextCast::to(&child).unwrap(); - data.push(text.get().characterdata.data.to_str()); // FIXME: Bad copy. + let text: &JSRef<Text> = TextCast::to_ref(&child).unwrap(); + data.push(text.deref().characterdata.data.to_str()); // FIXME: Bad copy. } debug!("script data = {:?}", data); diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index a9cd5edbaff..46609cc0614 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -5,19 +5,22 @@ //! The script task is the task that owns the DOM in memory, runs JavaScript, and spawns parsing //! and layout tasks. +use dom::attr::AttrMethods; use dom::bindings::codegen::RegisterBindings; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, ElementCast, EventCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalSettable}; +use dom::bindings::js::OptionalRootable; use dom::bindings::trace::{Traceable, Untraceable}; -use dom::bindings::utils::{Reflectable, GlobalStaticData, with_gc_enabled, wrap_for_same_compartment}; -use dom::document::{Document, HTMLDocument}; +use dom::bindings::utils::{Reflectable, GlobalStaticData, wrap_for_same_compartment}; +use dom::document::{Document, HTMLDocument, DocumentMethods, DocumentHelpers}; use dom::element::{Element, AttributeHandlers}; use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; -use dom::event::Event; -use dom::uievent::UIEvent; -use dom::eventtarget::EventTarget; +use dom::event::{Event, EventMethods}; +use dom::uievent::{UIEvent, UIEventMethods}; +use dom::eventtarget::{EventTarget, EventTargetHelpers}; +use dom::node; use dom::node::{Node, NodeHelpers}; -use dom::window::{TimerData, Window}; +use dom::window::{TimerId, Window}; use html::hubbub_html_parser::HtmlParserResult; use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript}; use html::hubbub_html_parser; @@ -32,8 +35,8 @@ use layout_interface; use geom::point::Point2D; use geom::size::Size2D; use js::global::DEBUG_FNS; -use js::jsapi::{JSObject, JS_InhibitGC, JS_AllowGC, JS_CallFunctionValue, JS_DefineFunctions}; -use js::jsapi::JS_SetWrapObjectCallbacks; +use js::jsapi::{JSObject, JS_CallFunctionValue, JS_DefineFunctions}; +use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ}; use js::jsval::NullValue; use js::rust::{Cx, RtUtils}; use js; @@ -52,6 +55,7 @@ use servo_util::namespace::Null; use std::cast; use std::cell::{RefCell, Ref, RefMut}; use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data}; +use std::local_data; use std::mem::replace; use std::ptr; use std::rc::Rc; @@ -60,6 +64,8 @@ use url::Url; use serialize::{Encoder, Encodable}; +local_data_key!(pub StackRoots: *RootCollection) + /// Messages used to control the script task. pub enum ScriptMsg { /// Loads a new URL on the specified pipeline. @@ -73,7 +79,7 @@ pub enum ScriptMsg { /// Window resized. Sends a DOM event eventually, but first we combine events. ResizeMsg(PipelineId, Size2D<uint>), /// Fires a JavaScript timeout. - FireTimerMsg(PipelineId, ~TimerData), + FireTimerMsg(PipelineId, TimerId), /// Notifies script that reflow is finished. ReflowCompleteMsg(PipelineId, uint), /// Notifies script that window has been resized but to not take immediate action. @@ -274,12 +280,12 @@ impl Page { pub fn damage(&self, level: DocumentDamageLevel) { let root = match *self.frame() { None => return, - Some(ref frame) => frame.document.get().GetDocumentElement() + Some(ref frame) => frame.document.root().GetDocumentElement() }; - match root { + match root.root() { None => {}, Some(root) => { - let root: JS<Node> = NodeCast::from(&root); + let root: &JSRef<Node> = NodeCast::from_ref(&*root); let mut damage = *self.damage.deref().borrow_mut(); match damage { None => {} @@ -351,14 +357,15 @@ impl Page { goal: ReflowGoal, script_chan: ScriptChan, compositor: &ScriptListener) { + let root = match *self.frame() { None => return, Some(ref frame) => { - frame.document.get().GetDocumentElement() + frame.document.root().GetDocumentElement() } }; - match root { + match root.root() { None => {}, Some(root) => { debug!("script: performing reflow for goal {:?}", goal); @@ -377,7 +384,7 @@ impl Page { let mut last_reflow_id = self.last_reflow_id.deref().borrow_mut(); *last_reflow_id += 1; - let root: JS<Node> = NodeCast::from(&root); + let root: &JSRef<Node> = NodeCast::from_ref(&*root); let mut damage = self.damage.deref().borrow_mut(); let window_size = self.window_size.deref().borrow(); @@ -401,19 +408,20 @@ impl Page { } } - fn find_fragment_node(&self, fragid: ~str) -> Option<JS<Element>> { - let document = self.frame().get_ref().document.clone(); - match document.get().GetElementById(fragid.to_owned()) { + fn find_fragment_node(&self, fragid: ~str) -> Option<Temporary<Element>> { + let document = self.frame().get_ref().document.root(); + match document.deref().GetElementById(fragid.to_owned()) { Some(node) => Some(node), None => { - let doc_node: JS<Node> = NodeCast::from(&document); - let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element()); + let doc_node: &JSRef<Node> = NodeCast::from_ref(&*document); + let mut anchors = doc_node.traverse_preorder() + .filter(|node| node.is_anchor_element()); anchors.find(|node| { - let elem: JS<Element> = ElementCast::to(node).unwrap(); - elem.get_attribute(Null, "name").map_or(false, |attr| { - attr.get().value_ref() == fragid + let elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); + elem.get_attribute(Null, "name").root().map_or(false, |attr| { + attr.deref().value_ref() == fragid }) - }).map(|node| ElementCast::to(&node).unwrap()) + }).map(|node| Temporary::from_rooted(ElementCast::to_ref(&node).unwrap())) } } } @@ -424,13 +432,13 @@ impl Page { // Note that the order that these variables are initialized is _not_ arbitrary. Switching // them around can -- and likely will -- lead to things breaking. - js_context.set_default_options_and_version(); - js_context.set_logging_error_reporter(); - unsafe { - JS_InhibitGC(js_context.deref().ptr); + JS_SetGCZeal(js_context.deref().ptr, 0, JS_DEFAULT_ZEAL_FREQ); } + js_context.set_default_options_and_version(); + js_context.set_logging_error_reporter(); + let mut js_info = self.mut_js_info(); *js_info = Some(JSPageInfo { dom_static: GlobalStaticData(), @@ -440,12 +448,13 @@ impl Page { pub fn hit_test(&self, point: &Point2D<f32>) -> Option<UntrustedNodeAddress> { let frame = self.frame(); - let document = frame.get_ref().document.clone(); - let root = document.get().GetDocumentElement(); + let document = frame.get_ref().document.root(); + let root = document.deref().GetDocumentElement().root(); if root.is_none() { return None; } - let root: JS<Node> = NodeCast::from(&root.unwrap()); + let root = root.unwrap(); + let root: &JSRef<Node> = NodeCast::from_ref(&*root); let (chan, port) = channel(); let address = match self.query_layout(HitTestQuery(root.to_trusted_node_address(), *point, chan), port) { Ok(HitTestResponse(node_address)) => { @@ -461,12 +470,13 @@ impl Page { pub fn get_nodes_under_mouse(&self, point: &Point2D<f32>) -> Option<Vec<UntrustedNodeAddress>> { let frame = self.frame(); - let document = frame.get_ref().document.clone(); - let root = document.get().GetDocumentElement(); + let document = frame.get_ref().document.root(); + let root = document.deref().GetDocumentElement().root(); if root.is_none() { return None; } - let root: JS<Node> = NodeCast::from(&root.unwrap()); + let root = root.unwrap(); + let root: &JSRef<Node> = NodeCast::from_ref(&*root); let (chan, port) = channel(); let address = match self.query_layout(MouseOverQuery(root.to_trusted_node_address(), *point, chan), port) { Ok(MouseOverResponse(node_address)) => { @@ -498,6 +508,21 @@ pub struct JSPageInfo { pub js_context: Untraceable<Rc<Cx>>, } +struct StackRootTLS; + +impl StackRootTLS { + fn new(roots: &RootCollection) -> StackRootTLS { + local_data::set(StackRoots, roots as *RootCollection); + StackRootTLS + } +} + +impl Drop for StackRootTLS { + fn drop(&mut self) { + let _ = local_data::pop(StackRoots); + } +} + /// Information for an entire page. Pages are top-level browsing contexts and can contain multiple /// frames. /// @@ -554,11 +579,7 @@ impl<'a> Drop for ScriptMemoryFailsafe<'a> { Some(owner) => { let mut page_tree = owner.page_tree.borrow_mut(); for page in page_tree.iter() { - let mut js_info = page.mut_js_info(); - unsafe { - JS_AllowGC(js_info.get_ref().js_context.deref().deref().ptr); - } - *js_info = None; + *page.mut_js_info() = None; } } None => (), @@ -645,6 +666,9 @@ impl ScriptTask { /// Handle incoming control messages. fn handle_msgs(&self) -> bool { + let roots = RootCollection::new(); + let _stack_roots_tls = StackRootTLS::new(&roots); + // Handle pending resize events. // Gather them first to avoid a double mut borrow on self. let mut resizes = vec!(); @@ -700,7 +724,7 @@ impl ScriptTask { AttachLayoutMsg(new_layout_info) => self.handle_new_layout(new_layout_info), LoadMsg(id, url) => self.load(id, url), SendEventMsg(id, event) => self.handle_event(id, event), - FireTimerMsg(id, timer_data) => self.handle_fire_timer_msg(id, timer_data), + FireTimerMsg(id, timer_id) => self.handle_fire_timer_msg(id, timer_id), NavigateMsg(direction) => self.handle_navigate_msg(direction), ReflowCompleteMsg(id, reflow_id) => self.handle_reflow_complete_msg(id, reflow_id), ResizeInactiveMsg(id, new_size) => self.handle_resize_inactive_msg(id, new_size), @@ -733,35 +757,35 @@ impl ScriptTask { } /// Handles a timer that fired. - fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) { + fn handle_fire_timer_msg(&self, id: PipelineId, timer_id: TimerId) { let mut page_tree = self.page_tree.borrow_mut(); let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a pipeline ID not associated with this script task. This is a bug.").page(); let frame = page.frame(); - let mut window = frame.get_ref().window.clone(); + let mut window = frame.get_ref().window.root(); - { - let timer_handle = window.get().active_timers.find(&timer_data.handle); - if timer_handle.is_none() { - return; + let this_value = window.deref().reflector().get_jsobject(); + + let is_interval; + match window.deref().active_timers.find(&timer_id) { + None => return, + Some(timer_handle) => { + // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. + let rval = NullValue(); + let js_info = page.js_info(); + let cx = js_info.get_ref().js_context.deref().deref().ptr; + unsafe { + JS_CallFunctionValue(cx, this_value, *timer_handle.data.funval, + 0, ptr::null(), &rval); + } + + is_interval = timer_handle.data.is_interval; } } - if !timer_data.is_interval { - window.get_mut().active_timers.remove(&timer_data.handle); + if !is_interval { + window.deref_mut().active_timers.remove(&timer_id); } - - let this_value = window.reflector().get_jsobject(); - - // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. - let rval = NullValue(); - let js_info = page.js_info(); - let cx = js_info.get_ref().js_context.deref().deref().ptr; - with_gc_enabled(cx, || { - unsafe { - JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval); - } - }); } /// Handles a notification that reflow completed. @@ -874,14 +898,14 @@ impl ScriptTask { page_tree.page.clone(), self.chan.clone(), self.compositor.dup(), - self.image_cache_task.clone()); + self.image_cache_task.clone()).root(); page.initialize_js_info(cx.clone(), window.reflector().get_jsobject()); - let mut document = Document::new(&window, Some(url.clone()), HTMLDocument, None); - window.get_mut().init_browser_context(&document); + let mut document = Document::new(&*window, Some(url.clone()), HTMLDocument, None).root(); + window.deref_mut().init_browser_context(&*document); { let mut js_info = page.mut_js_info(); - RegisterBindings::Register(&window, js_info.get_mut_ref()); + RegisterBindings::Register(&window.unrooted(), js_info.get_mut_ref()); } self.compositor.set_ready_state(Loading); @@ -889,7 +913,7 @@ impl ScriptTask { // // Note: We can parse the next document in parallel with any previous documents. let html_parsing_result = hubbub_html_parser::parse_html(page, - &mut document, + &mut *document, url.clone(), self.resource_task.clone()); @@ -901,8 +925,8 @@ impl ScriptTask { // Create the root frame. let mut frame = page.mut_frame(); *frame = Some(Frame { - document: document.clone(), - window: window.clone(), + document: document.deref().unrooted(), + window: window.deref().unrooted(), }); } @@ -941,7 +965,7 @@ impl ScriptTask { } // Kick off the initial reflow of the page. - document.get().content_changed(); + document.content_changed(); let fragment = url.fragment.as_ref().map(|ref fragment| fragment.to_owned()); @@ -965,36 +989,34 @@ impl ScriptTask { // Evaluate every script in the document. for file in js_scripts.iter() { - with_gc_enabled((*cx).ptr, || { - let global_obj = window.reflector().get_jsobject(); - //FIXME: this should have some kind of error handling, or explicitly - // drop an exception on the floor. - match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) { - Ok(_) => (), - Err(_) => println!("evaluate_script failed") - } - }); + let global_obj = window.reflector().get_jsobject(); + //FIXME: this should have some kind of error handling, or explicitly + // drop an exception on the floor. + match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) { + Ok(_) => (), + Err(_) => println!("evaluate_script failed") + } } // We have no concept of a document loader right now, so just dispatch the // "load" event as soon as we've finished executing all scripts parsed during // the initial load. - let mut event = Event::new(&window); - event.get_mut().InitEvent(~"load", false, false); - let doctarget = EventTargetCast::from(&document); - let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window); - let winclone = wintarget.clone(); - let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); + let mut event = Event::new(&*window).root(); + event.InitEvent(~"load", false, false); + let doctarget: &JSRef<EventTarget> = EventTargetCast::from_ref(&*document); + let wintarget: &JSRef<EventTarget> = EventTargetCast::from_ref(&*window); + let _ = wintarget.dispatch_event_with_target(Some((*doctarget).clone()), + &mut *event); let mut fragment_node = page.fragment_node.deref().borrow_mut(); - *fragment_node = fragment.map_or(None, |fragid| page.find_fragment_node(fragid)); + (*fragment_node).assign(fragment.map_or(None, |fragid| page.find_fragment_node(fragid))); let ConstellationChan(ref chan) = self.constellation_chan; chan.send(LoadCompleteMsg(page.id, url)); } - fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: JS<Element>) { - let node: JS<Node> = NodeCast::from(&node); + fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: &JSRef<Element>) { + let node: &JSRef<Node> = NodeCast::from_ref(node); let rect = node.get_bounding_content_box(); let point = Point2D(to_frac_px(rect.origin.x).to_f32().unwrap(), to_frac_px(rect.origin.y).to_f32().unwrap()); @@ -1009,48 +1031,52 @@ impl ScriptTask { /// /// TODO: Actually perform DOM event dispatch. fn handle_event(&self, pipeline_id: PipelineId, event: Event_) { - let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.find(pipeline_id).expect("ScriptTask: received an event - message for a layout channel that is not associated with this script task. This - is a bug.").page(); + fn get_page<'a>(page_tree: &'a mut PageTree, pipeline_id: PipelineId) -> &'a Page { + page_tree.find(pipeline_id).expect("ScriptTask: received an event \ + message for a layout channel that is not associated with this script task.\ + This is a bug.").page() + } match event { ResizeEvent(new_width, new_height) => { debug!("script got resize event: {:u}, {:u}", new_width, new_height); - { - let mut window_size = page.window_size.deref().borrow_mut(); - *window_size = Size2D(new_width, new_height); - } + let window = { + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); + { + let mut window_size = page.window_size.deref().borrow_mut(); + *window_size = Size2D(new_width, new_height); + } - { let frame = page.frame(); if frame.is_some() { page.damage(ReflowDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor) } - } - let mut fragment_node = page.fragment_node.deref().borrow_mut(); - match fragment_node.take() { - Some(node) => self.scroll_fragment_point(pipeline_id, node), - None => {} - } + let mut fragment_node = page.fragment_node.deref().borrow_mut(); + match fragment_node.take().map(|node| node.root()) { + Some(node) => self.scroll_fragment_point(pipeline_id, &*node), + None => {} + } - let frame = page.frame(); - match *frame { - Some(ref frame) => { + frame.as_ref().map(|frame| Temporary::new(frame.window.clone())) + }; + + match window.root() { + Some(mut window) => { // http://dev.w3.org/csswg/cssom-view/#resizing-viewports // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize - let mut uievent = UIEvent::new(&frame.window); - uievent.get_mut().InitUIEvent(~"resize", false, false, Some(frame.window.clone()), 0i32); - let event: &mut JS<Event> = &mut EventCast::from(&uievent); + let mut uievent = UIEvent::new(&*window).root(); + uievent.InitUIEvent(~"resize", false, false, + Some((*window).clone()), 0i32); + let event: &mut JSRef<Event> = EventCast::from_mut_ref(&mut *uievent); - let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window); - let winclone = wintarget.clone(); - let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, None, event); + let wintarget: &mut JSRef<EventTarget> = EventTargetCast::from_mut_ref(&mut *window); + let _ = wintarget.dispatch_event_with_target(None, &mut *event); } - None =>() + None => () } } @@ -1058,6 +1084,8 @@ impl ScriptTask { ReflowEvent => { debug!("script got reflow event"); + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); let frame = page.frame(); if frame.is_some() { page.damage(MatchSelectorsDocumentDamage); @@ -1067,27 +1095,29 @@ impl ScriptTask { ClickEvent(_button, point) => { debug!("ClickEvent: clicked at {:?}", point); + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); match page.hit_test(&point) { Some(node_address) => { debug!("node address is {:?}", node_address); - let mut node: JS<Node> = - NodeHelpers::from_untrusted_node_address(self.js_runtime.deref().ptr, - node_address); - debug!("clicked on {:s}", node.debug_str()); + let mut node = + node::from_untrusted_node_address(self.js_runtime.deref().ptr, + node_address).root(); + debug!("clicked on {:s}", node.deref().debug_str()); // Traverse node generations until a node that is an element is // found. - while !node.is_element() { - match node.parent_node() { - Some(parent) => node = parent, + while !node.deref().is_element() { + match node.deref().parent_node() { + Some(parent) => node = parent.root(), None => break, } } - if node.is_element() { - let element: JS<Element> = ElementCast::to(&node).unwrap(); - if "a" == element.get().local_name { - self.load_url_from_element(page, &element) + if node.deref().is_element() { + let element: &JSRef<Element> = ElementCast::to_ref(&*node).unwrap(); + if "a" == element.deref().local_name { + self.load_url_from_element(page, element) } } } @@ -1098,6 +1128,8 @@ impl ScriptTask { MouseDownEvent(..) => {} MouseUpEvent(..) => {} MouseMoveEvent(point) => { + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); match page.get_nodes_under_mouse(&point) { Some(node_address) => { @@ -1108,6 +1140,7 @@ impl ScriptTask { match *mouse_over_targets { Some(ref mut mouse_over_targets) => { for node in mouse_over_targets.mut_iter() { + let mut node = node.root(); node.set_hover_state(false); } } @@ -1115,14 +1148,14 @@ impl ScriptTask { } for node_address in node_address.iter() { - let mut node: JS<Node> = - NodeHelpers::from_untrusted_node_address( - self.js_runtime.deref().ptr, *node_address); + let mut node = + node::from_untrusted_node_address( + self.js_runtime.deref().ptr, *node_address).root(); // Traverse node generations until a node that is an element is // found. while !node.is_element() { match node.parent_node() { - Some(parent) => node = parent, + Some(parent) => node = parent.root(), None => break, } } @@ -1133,12 +1166,12 @@ impl ScriptTask { match *mouse_over_targets { Some(ref mouse_over_targets) => { if !target_compare { - target_compare = !mouse_over_targets.contains(&node); + target_compare = !mouse_over_targets.contains(&node.unrooted()); } } None => {} } - target_list.push(node); + target_list.push(node.unrooted()); } } match *mouse_over_targets { @@ -1165,19 +1198,19 @@ impl ScriptTask { } } - fn load_url_from_element(&self, page: &Page, element: &JS<Element>) { + fn load_url_from_element(&self, page: &Page, element: &JSRef<Element>) { // if the node's element is "a," load url from href attr let attr = element.get_attribute(Null, "href"); - for href in attr.iter() { - debug!("ScriptTask: clicked on link to {:s}", href.get().Value()); - let click_frag = href.get().value_ref().starts_with("#"); + for href in attr.root().iter() { + debug!("ScriptTask: clicked on link to {:s}", href.Value()); + let click_frag = href.deref().value_ref().starts_with("#"); let base_url = Some(page.get_url()); debug!("ScriptTask: current url is {:?}", base_url); - let url = parse_url(href.get().value_ref(), base_url); + let url = parse_url(href.deref().value_ref(), base_url); if click_frag { - match page.find_fragment_node(url.fragment.unwrap()) { - Some(node) => self.scroll_fragment_point(page.id, node), + match page.find_fragment_node(url.fragment.unwrap()).root() { + Some(node) => self.scroll_fragment_point(page.id, &*node), None => {} } } else { @@ -1202,9 +1235,6 @@ fn shut_down_layout(page: &Page) { // compartment to shutdown, run GC, etc. let mut js_info = page.mut_js_info(); - unsafe { - JS_AllowGC(js_info.get_ref().js_context.deref().deref().ptr); - } let mut frame = page.mut_frame(); *frame = None; |