diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 4 | ||||
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 31 | ||||
-rw-r--r-- | src/components/script/dom/bindings/codegen/Configuration.py | 1 | ||||
-rw-r--r-- | src/components/script/dom/bindings/codegen/HTMLDivElement.webidl | 19 | ||||
-rw-r--r-- | src/components/script/dom/bindings/element.rs | 36 | ||||
-rw-r--r-- | src/components/script/dom/bindings/node.rs | 4 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/element.rs | 183 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 11 | ||||
-rw-r--r-- | src/components/script/script.rc | 1 |
10 files changed, 161 insertions, 131 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index fe63f585a55..597fba5cddf 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -169,7 +169,8 @@ DOMInterfaces = { 'Element': { 'nativeType': 'AbstractNode<ScriptView>', - 'pointerType': '' + 'pointerType': '', + 'needsAbstract': ['getClientRects', 'getBoundingClientRect'] }, 'Event': { @@ -545,6 +546,7 @@ def addHTMLElement(element): } addHTMLElement('HTMLAnchorElement') +addHTMLElement('HTMLDivElement') addHTMLElement('HTMLElement') addHTMLElement('HTMLHeadElement') addHTMLElement('HTMLHtmlElement') diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 490f7f06ecf..5ff90888c3d 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -3177,7 +3177,7 @@ class CGGenericMethod(CGAbstractBindingMethod): def generate_code(self): return CGIndenter(CGGeneric( "let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" - "return CallJitMethodOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, argc, vp);")) + "return CallJitMethodOp(_info, cx, obj, this as *libc::c_void, argc, vp);")) class CGAbstractStaticMethod(CGAbstractMethod): """ @@ -3200,16 +3200,24 @@ class CGSpecializedMethod(CGAbstractExternMethod): self.method = method name = method.identifier.name args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'), - Argument('*mut %s' % descriptor.concreteType, 'this'), + Argument('*mut rust_box<%s>' % descriptor.concreteType, 'this'), Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')] CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args) def definition_body(self): name = self.method.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) - return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(), + extraPre = '' + argsPre = [] + if name in self.descriptor.needsAbstract: + abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) + extraPre = ' let abstract_this = %s::from_box(this);\n' % abstractName + argsPre = ['abstract_this'] + return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(), self.descriptor, self.method), - pre=" let obj = (*obj.unnamed);\n").define() + pre=extraPre + + " let obj = (*obj.unnamed);\n" + + " let this = &mut (*this).payload;\n").define() class CGGenericGetter(CGAbstractBindingMethod): """ @@ -3233,7 +3241,7 @@ class CGGenericGetter(CGAbstractBindingMethod): def generate_code(self): return CGIndenter(CGGeneric( "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" - "return CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, vp);")) + "return CallJitPropertyOp(info, cx, obj, this as *libc::c_void, vp);")) class CGSpecializedGetter(CGAbstractExternMethod): """ @@ -3245,7 +3253,7 @@ class CGSpecializedGetter(CGAbstractExternMethod): name = 'get_' + attr.identifier.name args = [ Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'), - Argument('*%s' % descriptor.concreteType, 'this'), + Argument('*mut rust_box<%s>' % descriptor.concreteType, 'this'), Argument('*mut JSVal', 'vp') ] CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) @@ -3263,7 +3271,8 @@ class CGSpecializedGetter(CGAbstractExternMethod): nativeName = "Get" + nativeName return CGWrapper(CGIndenter(CGGetterCall(self.attr.type, nativeName, self.descriptor, self.attr)), - pre=" let obj = (*obj.unnamed);\n").define() + pre=" let obj = (*obj.unnamed);\n" + + " let this = &mut (*this).payload;\n").define() class CGGenericSetter(CGAbstractBindingMethod): """ @@ -3288,7 +3297,7 @@ class CGGenericSetter(CGAbstractBindingMethod): "let undef = JSVAL_VOID;\n" "let argv: *JSVal = if argc != 0 { JS_ARGV(cx, cast::transmute(vp)) } else { &undef as *JSVal };\n" "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, cast::transmute(vp)));\n" - "if CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, argv) == 0 {" + "if CallJitPropertyOp(info, cx, obj, this as *libc::c_void, argv) == 0 {" " return 0;\n" "}\n" "*vp = JSVAL_VOID;\n" @@ -3304,7 +3313,7 @@ class CGSpecializedSetter(CGAbstractExternMethod): name = 'set_' + attr.identifier.name args = [ Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'), - Argument('*mut %s' % descriptor.concreteType, 'this'), + Argument('*mut rust_box<%s>' % descriptor.concreteType, 'this'), Argument('*mut JSVal', 'argv')] CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) @@ -3313,7 +3322,8 @@ class CGSpecializedSetter(CGAbstractExternMethod): nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name)) return CGWrapper(CGIndenter(CGSetterCall(self.attr.type, nativeName, self.descriptor, self.attr)), - pre=" let obj = (*obj.unnamed);\n").define() + pre=" let obj = (*obj.unnamed);\n" + + " let this = &mut (*this).payload;\n").define() def infallibleForMember(member, type, descriptorProvider): """ @@ -4606,6 +4616,7 @@ class CGBindingRoot(CGThing): 'dom::node::{AbstractNode, Node, Text}', #XXXjdm 'dom::document::{Document, AbstractDocument}', #XXXjdm 'dom::element::{Element, HTMLHeadElement, HTMLHtmlElement}', #XXXjdm + 'dom::element::{HTMLDivElement}', #XXXjdm 'dom::htmlanchorelement::HTMLAnchorElement', #XXXjdm 'dom::htmlelement::HTMLElement', #XXXjdm 'dom::htmldocument::HTMLDocument', #XXXjdm diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py index cf2c13b504e..d597da940e4 100644 --- a/src/components/script/dom/bindings/codegen/Configuration.py +++ b/src/components/script/dom/bindings/codegen/Configuration.py @@ -141,6 +141,7 @@ class Descriptor(DescriptorProvider): self.nativeType = desc.get('nativeType', nativeTypeDefault) self.pointerType = desc.get('pointerType', '@mut ') self.concreteType = desc.get('concreteType', ifaceName) + self.needsAbstract = desc.get('needsAbstract', []) self.hasInstanceInterface = desc.get('hasInstanceInterface', None) # Do something sane for JSObject diff --git a/src/components/script/dom/bindings/codegen/HTMLDivElement.webidl b/src/components/script/dom/bindings/codegen/HTMLDivElement.webidl new file mode 100644 index 00000000000..f50e2aad003 --- /dev/null +++ b/src/components/script/dom/bindings/codegen/HTMLDivElement.webidl @@ -0,0 +1,19 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://www.whatwg.org/specs/web-apps/current-work/ + * + * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and + * Opera Software ASA. You are granted a license to use, reproduce + * and create derivative works of this document. + */ + +interface HTMLDivElement : HTMLElement {}; + +partial interface HTMLDivElement { + [SetterThrows] + attribute DOMString align; +}; diff --git a/src/components/script/dom/bindings/element.rs b/src/components/script/dom/bindings/element.rs index 2c136083540..a177c10c332 100644 --- a/src/components/script/dom/bindings/element.rs +++ b/src/components/script/dom/bindings/element.rs @@ -29,8 +29,8 @@ use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec}; use js::jsapi::{JSNativeWrapper, JSTracer, JSTRACE_OBJECT}; use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper, JSFunctionSpec}; use js::rust::{Compartment, jsobj}; -use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL}; -use js::{JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS}; +use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED}; +use js::{JS_THIS_OBJECT, JSPROP_NATIVE_ACCESSORS}; extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { debug!("element finalize: %x!", obj as uint); @@ -151,17 +151,13 @@ extern fn getClientRects(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool { let obj = JS_THIS_OBJECT(cx, vp); let mut node = unwrap(obj); let rval = do node.with_imm_element |elem| { - elem.getClientRects() + elem.GetClientRects(node) }; - if rval.is_none() { - JS_SET_RVAL(cx, vp, JSVAL_NULL); - } else { - let cache = node.get_wrappercache(); - let rval = rval.get() as @mut CacheableWrapper; - assert!(WrapNewBindingObject(cx, cache.get_wrapper(), - rval, - cast::transmute(vp))); - } + let cache = node.get_wrappercache(); + let rval = rval as @mut CacheableWrapper; + assert!(WrapNewBindingObject(cx, cache.get_wrapper(), + rval, + cast::transmute(vp))); return 1; } } @@ -171,17 +167,13 @@ extern fn getBoundingClientRect(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JS let obj = JS_THIS_OBJECT(cx, vp); let mut node = unwrap(obj); let rval = do node.with_imm_element |elem| { - elem.getBoundingClientRect() + elem.GetBoundingClientRect(node) }; - if rval.is_none() { - JS_SET_RVAL(cx, vp, JSVAL_NULL); - } else { - let cache = node.get_wrappercache(); - let rval = rval.get() as @mut CacheableWrapper; - assert!(WrapNewBindingObject(cx, cache.get_wrapper(), - rval, - cast::transmute(vp))); - } + let cache = node.get_wrappercache(); + let rval = rval as @mut CacheableWrapper; + assert!(WrapNewBindingObject(cx, cache.get_wrapper(), + rval, + cast::transmute(vp))); return 1; } } diff --git a/src/components/script/dom/bindings/node.rs b/src/components/script/dom/bindings/node.rs index ccbb676b2b4..459d25bde4e 100644 --- a/src/components/script/dom/bindings/node.rs +++ b/src/components/script/dom/bindings/node.rs @@ -7,7 +7,8 @@ use dom::bindings::text; use dom::bindings::utils; use dom::bindings::utils::{CacheableWrapper, WrapperCache, DerivedWrapper}; use dom::element::{HTMLHeadElementTypeId, HTMLHtmlElementTypeId, HTMLAnchorElementTypeId}; -use dom::element::{HTMLHeadElement, HTMLHtmlElement}; +use dom::element::{HTMLDivElementTypeId}; +use dom::element::{HTMLHeadElement, HTMLHtmlElement, HTMLDivElement}; use dom::htmlanchorelement::HTMLAnchorElement; use dom::node::{AbstractNode, Node, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId}; use dom::node::{DoctypeNodeTypeId, ScriptView, Text}; @@ -75,6 +76,7 @@ macro_rules! generate_element( pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject { match node.type_id() { ElementNodeTypeId(HTMLAnchorElementTypeId) => generate_element!(HTMLAnchorElement), + ElementNodeTypeId(HTMLDivElementTypeId) => generate_element!(HTMLDivElement), ElementNodeTypeId(HTMLHeadElementTypeId) => generate_element!(HTMLHeadElement), ElementNodeTypeId(HTMLHtmlElementTypeId) => generate_element!(HTMLHtmlElement), ElementNodeTypeId(_) => element::create(cx, node).ptr, diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index cc1b09eb081..1fd07d415fc 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -617,7 +617,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> } pub fn initialize_global(global: *JSObject) { - let protoArray = @mut ([0 as *JSObject, ..33]); //XXXjdm PrototyepList::id::_ID_Count + let protoArray = @mut ([0 as *JSObject, ..34]); //XXXjdm PrototyepList::id::_ID_Count unsafe { //XXXjdm we should be storing the box pointer instead of the inner let box = squirrel_away(protoArray); diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 8ff300fe1b7..3459d2dd06f 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -5,7 +5,7 @@ //! Element nodes. use dom::bindings::codegen::{HTMLHeadElementBinding, HTMLHtmlElementBinding}; -use dom::bindings::codegen::{HTMLAnchorElementBinding}; +use dom::bindings::codegen::{HTMLAnchorElementBinding, HTMLDivElementBinding}; use dom::bindings::utils::{DOMString, null_string, ErrorResult}; use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache}; use dom::clientrect::ClientRect; @@ -134,6 +134,15 @@ impl HTMLHtmlElement { } } +impl HTMLDivElement { + pub fn Align(&self) -> DOMString { + null_string + } + + pub fn SetAlign(&mut self, _align: &DOMString, _rv: &mut ErrorResult) { + } +} + pub macro_rules! generate_cacheable_wrapper( ($name: ident, $wrap: path) => ( impl CacheableWrapper for $name { @@ -165,6 +174,8 @@ generate_cacheable_wrapper!(HTMLHtmlElement, HTMLHtmlElementBinding::Wrap) generate_binding_object!(HTMLHtmlElement) generate_cacheable_wrapper!(HTMLAnchorElement, HTMLAnchorElementBinding::Wrap) generate_binding_object!(HTMLAnchorElement) +generate_cacheable_wrapper!(HTMLDivElement, HTMLDivElementBinding::Wrap) +generate_binding_object!(HTMLDivElement) // // Fancier elements @@ -233,95 +244,6 @@ impl<'self> Element { } } - pub fn getClientRects(&self) -> Option<@mut ClientRectList> { - let (rects, cx, scope) = match self.parent.owner_doc { - Some(doc) => { - match doc.with_base(|doc| doc.window) { - Some(win) => { - let node = self.parent.abstract.get(); - assert!(node.is_element()); - let page = win.page; - let (port, chan) = comm::stream(); - // TODO(tkuehn): currently just queries top-level page layout. Needs to query - // subframe layout if this element is in a subframe. Probably need an ID field. - match unsafe {(*page).query_layout(ContentBoxesQuery(node, chan), port)} { - Ok(ContentBoxesResponse(rects)) => { - let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); - let rects = do rects.map |r| { - ClientRect::new( - r.origin.y.to_f32(), - (r.origin.y + r.size.height).to_f32(), - r.origin.x.to_f32(), - (r.origin.x + r.size.width).to_f32(), - cx, - scope) - }; - Some((rects, cx, scope)) - }, - Err(()) => { - debug!("layout query error"); - None - } - } - } - None => { - debug!("no window"); - None - } - } - } - None => { - debug!("no document"); - None - } - }.get(); - - Some(ClientRectList::new(rects, cx, scope)) - } - - pub fn getBoundingClientRect(&self) -> Option<@mut ClientRect> { - match self.parent.owner_doc { - Some(doc) => { - match doc.with_base(|doc| doc.window) { - Some(win) => { - let page = win.page; - let node = self.parent.abstract.get(); - assert!(node.is_element()); - let (port, chan) = comm::stream(); - match unsafe{(*page).query_layout(ContentBoxQuery(node, chan), port)} { - Ok(ContentBoxResponse(rect)) => { - let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); - Some(ClientRect::new( - rect.origin.y.to_f32(), - (rect.origin.y + rect.size.height).to_f32(), - rect.origin.x.to_f32(), - (rect.origin.x + rect.size.width).to_f32(), - cx, - scope)) - }, - Err(()) => { - debug!("error querying layout"); - None - } - } - } - None => { - debug!("no window"); - None - } - } - } - None => { - debug!("no document"); - None - } - } - } - fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { let doc = self.parent.owner_doc.get(); let win = doc.with_base(|doc| doc.window.get()); @@ -405,13 +327,84 @@ impl Element { pub fn MozRequestPointerLock(&self) { } - pub fn GetClientRects(&self) -> @mut ClientRectList { - let (scope, cx) = self.get_scope_and_cx(); - ClientRectList::new(~[], cx, scope) + pub fn GetClientRects(&self, abstract_self: AbstractNode<ScriptView>) -> @mut ClientRectList { + let (rects, cx, scope) = match self.parent.owner_doc { + Some(doc) => { + match doc.with_base(|doc| doc.window) { + Some(win) => { + let node = abstract_self; + assert!(node.is_element()); + let page = win.page; + let (port, chan) = comm::stream(); + // TODO(tkuehn): currently just queries top-level page layout. Needs to query + // subframe layout if this element is in a subframe. Probably need an ID field. + match unsafe {(*page).query_layout(ContentBoxesQuery(node, chan), port)} { + Ok(ContentBoxesResponse(rects)) => { + let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr}; + let cache = win.get_wrappercache(); + let scope = cache.get_wrapper(); + let rects = do rects.map |r| { + ClientRect::new( + r.origin.y.to_f32(), + (r.origin.y + r.size.height).to_f32(), + r.origin.x.to_f32(), + (r.origin.x + r.size.width).to_f32(), + cx, + scope) + }; + Some((rects, cx, scope)) + }, + Err(()) => { + debug!("layout query error"); + None + } + } + } + None => { + debug!("no window"); + None + } + } + } + None => { + debug!("no document"); + None + } + }.get(); + + ClientRectList::new(rects, cx, scope) } - pub fn GetBoundingClientRect(&self) -> @mut ClientRect { - fail!("stub") + pub fn GetBoundingClientRect(&self, abstract_self: AbstractNode<ScriptView>) -> @mut ClientRect { + match self.parent.owner_doc { + Some(doc) => { + match doc.with_base(|doc| doc.window) { + Some(win) => { + let page = win.page; + let node = abstract_self; + assert!(node.is_element()); + let (port, chan) = comm::stream(); + match unsafe{(*page).query_layout(ContentBoxQuery(node, chan), port)} { + Ok(ContentBoxResponse(rect)) => { + let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr}; + let cache = win.get_wrappercache(); + let scope = cache.get_wrapper(); + ClientRect::new( + rect.origin.y.to_f32(), + (rect.origin.y + rect.size.height).to_f32(), + rect.origin.x.to_f32(), + (rect.origin.x + rect.size.width).to_f32(), + cx, + scope) + }, + Err(()) => fail!("error querying layout") + } + } + None => fail!("no window") + } + } + None => fail!("no document") + } } pub fn ScrollIntoView(&self, _top: bool) { diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 258717492af..920eb7a003c 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::TextBinding; use dom::bindings::node; use dom::bindings::utils::{WrapperCache, DOMString, null_string, ErrorResult}; -use dom::bindings::utils::{BindingObject, CacheableWrapper}; +use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box}; use dom::bindings; use dom::characterdata::CharacterData; use dom::document::AbstractDocument; @@ -235,6 +235,15 @@ impl<'self, View> AbstractNode<View> { } } + /// Allow consumers to recreate an AbstractNode from the raw boxed type. + /// Must only be used in situations where the boxed type is in the inheritance + /// chain for nodes. + pub fn from_box<T>(ptr: *mut rust_box<T>) -> AbstractNode<View> { + AbstractNode { + obj: ptr as *mut Node<View> + } + } + /// Returns the layout data, unsafely cast to whatever type layout wishes. Only layout is /// allowed to call this. This is wildly unsafe and is therefore marked as such. pub unsafe fn unsafe_layout_data<T>(self) -> @mut T { diff --git a/src/components/script/script.rc b/src/components/script/script.rc index b8f8a8697f4..989e472ddb8 100644 --- a/src/components/script/script.rc +++ b/src/components/script/script.rc @@ -44,6 +44,7 @@ pub mod dom { pub mod FormDataBinding; pub mod HTMLAnchorElementBinding; pub mod HTMLCollectionBinding; + pub mod HTMLDivElementBinding; pub mod HTMLDocumentBinding; pub mod HTMLElementBinding; pub mod HTMLHeadElementBinding; |