From 07c17fdef49f47af92a8777c6f662a5854afe51b Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 21 Aug 2012 22:42:38 -0700 Subject: [PATCH] Add further HMTL element prototype hierarchy. Add HTMLImageElement.width getter/setter that interacts with layout. --- src/rust-mozjs | 2 +- src/servo/content/content_task.rs | 2 +- src/servo/dom/base.rs | 7 +- src/servo/dom/bindings/document.rs | 60 ++---------- src/servo/dom/bindings/element.rs | 145 +++++++++++++++++++++++++++++ src/servo/dom/bindings/node.rs | 117 +++-------------------- src/servo/dom/bindings/utils.rs | 59 +++++++++++- src/servo/dom/bindings/window.rs | 41 ++------ src/servo/gfx/geometry.rs | 14 +-- src/servo/layout/inline.rs | 4 +- src/servo/servo.rc | 1 + src/test/test-js-image.html | 3 + src/test/test_image_getter.js | 6 ++ 13 files changed, 250 insertions(+), 211 deletions(-) create mode 100644 src/servo/dom/bindings/element.rs create mode 100644 src/test/test-js-image.html create mode 100644 src/test/test_image_getter.js diff --git a/src/rust-mozjs b/src/rust-mozjs index 1a01c0063a4..9bf630c5f20 160000 --- a/src/rust-mozjs +++ b/src/rust-mozjs @@ -1 +1 @@ -Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02 +Subproject commit 9bf630c5f2035a29e7ccee0ca94e9c4568815f7b diff --git a/src/servo/content/content_task.rs b/src/servo/content/content_task.rs index e48b4cc944e..133b3a0e91a 100644 --- a/src/servo/content/content_task.rs +++ b/src/servo/content/content_task.rs @@ -136,7 +136,7 @@ struct Content { #debug["js_scripts: %?", js_scripts]; let document = Document(root, css_rules); - let window = Window(root); + let window = Window(); self.relayout(document, &url); self.document = some(@document); self.window = some(@window); diff --git a/src/servo/dom/base.rs b/src/servo/dom/base.rs index 9a4fafc80da..ca85138d247 100644 --- a/src/servo/dom/base.rs +++ b/src/servo/dom/base.rs @@ -16,9 +16,9 @@ import std::arc::arc; import style::Stylesheet; struct Window { - let root: Node; - new(root: Node) { - self.root = root; + let unused: int; + new() { + self.unused = 0; } } @@ -81,6 +81,7 @@ fn define_bindings(compartment: bare_compartment, doc: @Document, bindings::window::init(compartment, win); bindings::document::init(compartment, doc); bindings::node::init(compartment); + bindings::element::init(compartment); } enum ElementKind { diff --git a/src/servo/dom/bindings/document.rs b/src/servo/dom/bindings/document.rs index b4a72d96224..4ec4ef81d66 100644 --- a/src/servo/dom/bindings/document.rs +++ b/src/servo/dom/bindings/document.rs @@ -10,10 +10,10 @@ import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ import result::{result, ok, err}; import ptr::null; import libc::c_uint; -import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str, - Document_class}; +import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str}; import bindings::node::create; -import base::{Document, Node}; +import base::Document; +import option::{some, none}; enum DOMException { INVALID_CHARACTER_ERR @@ -60,8 +60,6 @@ enum Element = int; return 1; }*/ -// Unfortunately duplicated in document and window. -// Generalizing it triggers a trans bug extern fn getDocumentElement(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool unsafe { let node = (*unwrap(obj)).payload.root; *rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr); @@ -83,50 +81,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { } fn init(compartment: bare_compartment, doc: @Document) { - fn DocumentProto_class(compartment: bare_compartment) -> JSClass { - {name: compartment.add_name(~"DOMDocumentPrototype"), - flags: 0, - addProperty: JS_PropertyStub, - delProperty: JS_PropertyStub, - getProperty: JS_PropertyStub, - setProperty: JS_StrictPropertyStub, - enumerate: JS_EnumerateStub, - resolve: JS_ResolveStub, - convert: JS_ConvertStub, - finalize: null(), - checkAccess: null(), - call: null(), - construct: null(), - hasInstance: utils::has_instance, - trace: null(), - reserved: (null(), null(), null(), null(), null(), // 05 - null(), null(), null(), null(), null(), // 10 - null(), null(), null(), null(), null(), // 15 - null(), null(), null(), null(), null(), // 20 - null(), null(), null(), null(), null(), // 25 - null(), null(), null(), null(), null(), // 30 - null(), null(), null(), null(), null(), // 35 - null(), null(), null(), null(), null())} // 40 - }; - - compartment.register_class(DocumentProto_class); - compartment.register_class(|c| Document_class(c, ~"DOMDocument", - finalize)); - - //TODO error checking - let obj = result::unwrap( - compartment.new_object(~"DOMDocumentPrototype", - null(), - compartment.global_obj.ptr)); - - /*let methods = ~[ - {name: compartment.add_name("getDocumentURI"), - call: getDocumentURI, - nargs: 0, - flags: 0}]; - vec::as_buf(methods, |fns| { - JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns); - });*/ + let obj = utils::define_empty_prototype(~"Document", none, compartment); let attrs = @~[ {name: compartment.add_name(~"documentElement"), @@ -139,13 +94,10 @@ fn init(compartment: bare_compartment, doc: @Document) { JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); }); - compartment.define_property(~"Document", RUST_OBJECT_TO_JSVAL(obj.ptr), - JS_PropertyStub, JS_StrictPropertyStub, - JSPROP_ENUMERATE); + compartment.register_class(utils::instance_jsclass(~"DocumentInstance", finalize)); let instance = result::unwrap( - //compartment.new_object(Document_class, null(), compartment.global_obj.ptr)); - compartment.new_object_with_proto(~"DOMDocument", ~"DOMDocumentPrototype", + compartment.new_object_with_proto(~"DocumentInstance", ~"Document", compartment.global_obj.ptr)); unsafe { diff --git a/src/servo/dom/bindings/element.rs b/src/servo/dom/bindings/element.rs new file mode 100644 index 00000000000..922381f9c17 --- /dev/null +++ b/src/servo/dom/bindings/element.rs @@ -0,0 +1,145 @@ +import js::rust::{bare_compartment, methods, jsobj}; +import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, + JS_THIS_OBJECT, JS_SET_RVAL}; +import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec}; +import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError, + JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN, + JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate}; +import js::jsapi::bindgen::*; +import js::glue::bindgen::*; +import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub}; + +import dom::base::{Node, Element}; +import utils::{rust_box, squirrel_away_unique, get_compartment, domstring_to_jsval, str}; +import libc::c_uint; +import ptr::null; +import node::unwrap; +import dom::base::{HTMLImageElement, HTMLScriptElement, HTMLHeadElement, HTMLDivElement, + UnknownElement}; +import gfx::geometry::{au_to_px, px_to_au}; + +extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { + #debug("element finalize!"); + unsafe { + let val = JS_GetReservedSlot(obj, 0); + let _node: ~Node = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val)); + } +} + +fn init(compartment: bare_compartment) { + let obj = utils::define_empty_prototype(~"Element", some(~"Node"), compartment); + let attrs = @~[ + {name: compartment.add_name(~"tagName"), + tinyid: 0, + flags: 0, + getter: getTagName, + setter: null()}]; + vec::push(compartment.global_props, attrs); + vec::as_buf(*attrs, |specs, _len| { + JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); + }); + + compartment.register_class(utils::instance_jsclass(~"GenericElementInstance", + finalize)); + + let _ = utils::define_empty_prototype(~"HTMLElement", some(~"Element"), compartment); + let _ = utils::define_empty_prototype(~"HTMLDivElement", some(~"HTMLElement"), compartment); + let _ = utils::define_empty_prototype(~"HTMLScriptElement", some(~"HTMLElement"), compartment); + let _ = utils::define_empty_prototype(~"HTMLHeadElement", some(~"HTMLElement"), compartment); + + let obj = utils::define_empty_prototype(~"HTMLImageElement", some(~"HTMLElement"), compartment); + let attrs = @~[ + {name: compartment.add_name(~"width"), + tinyid: 0, + flags: (JSPROP_SHARED | JSPROP_ENUMERATE) as u8, + getter: HTMLImageElement_getWidth, + setter: HTMLImageElement_setWidth}]; + vec::push(compartment.global_props, attrs); + vec::as_buf(*attrs, |specs, _len| { + JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); + }); +} + +extern fn HTMLImageElement_getWidth(_cx: *JSContext, obj: *JSObject, _id: jsid, + rval: *mut jsval) -> JSBool unsafe { + let width = (*unwrap(obj)).payload.read(|nd| { + match nd.kind { + ~Element(ed) => { + match ed.kind { + ~HTMLImageElement(img) => img.size.width, + _ => fail ~"why is this not an image element?" + } + } + _ => fail ~"why is this not an element?" + } + }); + *rval = RUST_INT_TO_JSVAL( + (au_to_px(width) & (i32::max_value as int)) as libc::c_int); + return 1; +} + +extern fn HTMLImageElement_setWidth(_cx: *JSContext, obj: *JSObject, _id: jsid, + _strict: JSBool, vp: *jsval) -> JSBool unsafe { + let width = (*unwrap(obj)).payload.read(|nd| { + match nd.kind { + ~Element(ed) => { + match ed.kind { + ~HTMLImageElement(img) => + img.size.width = px_to_au(RUST_JSVAL_TO_INT(*vp) as int), + _ => fail ~"why is this not an image element?" + } + } + _ => fail ~"why is this not an element?" + } + }); + return 1; +} + +extern fn getTagName(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) + -> JSBool { + unsafe { + (*unwrap(obj)).payload.read(|nd| { + match nd.kind { + ~Element(ed) => { + let s = str(copy ed.tag_name); + *rval = domstring_to_jsval(cx, s); + } + _ => { + //XXXjdm should probably read the spec to figure out what to do here + *rval = JSVAL_NULL; + } + } + }); + } + return 1; +} + +fn create(cx: *JSContext, node: Node) -> jsobj unsafe { + let proto = node.read(|nd| { + match nd.kind { + ~Element(ed) => { + match ed.kind { + ~HTMLDivElement(*) => ~"HTMLDivElement", + ~HTMLHeadElement(*) => ~"HTMLHeadElement", + ~HTMLImageElement(*) => ~"HTMLImageElement", + ~HTMLScriptElement(*) => ~"HTMLScriptElement", + ~UnknownElement(*) => ~"HTMLElement" + } + } + _ => fail ~"element::create only handles elements" + } + }); + + //XXXjdm the parent should probably be the node parent instead of the global + //TODO error checking + let compartment = utils::get_compartment(cx); + let obj = result::unwrap( + (*compartment).new_object_with_proto(~"GenericElementInstance", proto, + (*compartment).global_obj.ptr)); + + unsafe { + let raw_ptr: *libc::c_void = unsafe::reinterpret_cast(squirrel_away_unique(~node)); + JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); + } + return obj; +} diff --git a/src/servo/dom/bindings/node.rs b/src/servo/dom/bindings/node.rs index d8514fe440f..4f378bcd8c8 100644 --- a/src/servo/dom/bindings/node.rs +++ b/src/servo/dom/bindings/node.rs @@ -9,78 +9,14 @@ import js::jsapi::bindgen::*; import js::glue::bindgen::*; import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub}; -import dom::base::{Node, Element}; +import dom::base::{Node, Element, Text}; import utils::{rust_box, squirrel_away_unique, get_compartment, domstring_to_jsval, str}; import libc::c_uint; import ptr::null; -extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { - #debug("node finalize!"); - unsafe { - let val = JS_GetReservedSlot(obj, 0); - let _node: ~Node = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val)); - } -} - fn init(compartment: bare_compartment) { - fn NodeProto_class(compartment: bare_compartment) -> JSClass { - {name: compartment.add_name(~"NodePrototype"), - flags: 0, - addProperty: JS_PropertyStub, - delProperty: JS_PropertyStub, - getProperty: JS_PropertyStub, - setProperty: JS_StrictPropertyStub, - enumerate: JS_EnumerateStub, - resolve: JS_PropertyStub, - convert: JS_ConvertStub, - finalize: null(), - checkAccess: null(), - call: null(), - construct: null(), - hasInstance: utils::has_instance, - trace: null(), - reserved: (null(), null(), null(), null(), null(), // 05 - null(), null(), null(), null(), null(), // 10 - null(), null(), null(), null(), null(), // 15 - null(), null(), null(), null(), null(), // 20 - null(), null(), null(), null(), null(), // 25 - null(), null(), null(), null(), null(), // 30 - null(), null(), null(), null(), null(), // 35 - null(), null(), null(), null(), null())} // 40 - }; + let obj = utils::define_empty_prototype(~"Node", none, compartment); - fn Node_class(compartment: bare_compartment) -> JSClass { - {name: compartment.add_name(~"Node"), - flags: JSCLASS_HAS_RESERVED_SLOTS(1), - addProperty: JS_PropertyStub, - delProperty: JS_PropertyStub, - getProperty: JS_PropertyStub, - setProperty: JS_StrictPropertyStub, - enumerate: JS_EnumerateStub, - resolve: JS_PropertyStub, - convert: JS_ConvertStub, - finalize: finalize, - checkAccess: null(), - call: null(), - construct: null(), - hasInstance: utils::has_instance, - trace: null(), - reserved: (null(), null(), null(), null(), null(), // 05 - null(), null(), null(), null(), null(), // 10 - null(), null(), null(), null(), null(), // 15 - null(), null(), null(), null(), null(), // 20 - null(), null(), null(), null(), null(), // 25 - null(), null(), null(), null(), null(), // 30 - null(), null(), null(), null(), null(), // 35 - null(), null(), null(), null(), null())} // 40 - }; - - compartment.register_class(NodeProto_class); - compartment.register_class(Node_class); - - let obj = result::unwrap( - compartment.new_object(~"NodePrototype", null(), - compartment.global_obj.ptr)); let attrs = @~[ {name: compartment.add_name(~"firstChild"), tinyid: 0, @@ -92,38 +28,25 @@ fn init(compartment: bare_compartment) { tinyid: 0, flags: 0, getter: getNextSibling, - setter: null()}, - - {name: compartment.add_name(~"tagName"), - tinyid: 0, - flags: 0, - getter: getTagName, setter: null()}]; vec::push(compartment.global_props, attrs); vec::as_buf(*attrs, |specs, _len| { JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); }); - - compartment.define_property(~"Node", RUST_OBJECT_TO_JSVAL(obj.ptr), - JS_PropertyStub, JS_StrictPropertyStub, - JSPROP_ENUMERATE); } fn create(cx: *JSContext, node: Node) -> jsobj unsafe { - let compartment = get_compartment(cx); + do node.read |nd| { + match nd.kind { + ~Element(ed) => { + element::create(cx, node) + } - //XXXjdm the parent should probably be the node parent instead of the global - //TODO error checking - let obj = result::unwrap( - (*compartment).new_object_with_proto(~"Node", ~"NodePrototype", - (*compartment).global_obj.ptr)); - - unsafe { - let raw_ptr: *libc::c_void = unsafe::reinterpret_cast(squirrel_away_unique(~node)); - JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); + ~Text(s) => { + fail ~"no text node bindings yet"; + } + } } - - return obj; } unsafe fn unwrap(obj: *JSObject) -> *rust_box { @@ -164,21 +87,3 @@ extern fn getNextSibling(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut j } return 1; } - -extern fn getTagName(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool { - unsafe { - (*unwrap(obj)).payload.read(|nd| { - match nd.kind { - ~Element(ed) => { - let s = str(copy ed.tag_name); - *rval = domstring_to_jsval(cx, s); - } - _ => { - //XXXjdm should probably read the spec to figure out what to do here - *rval = JSVAL_NULL; - } - } - }); - } - return 1; -} diff --git a/src/servo/dom/bindings/utils.rs b/src/servo/dom/bindings/utils.rs index ad37135ea63..64437aa24fd 100644 --- a/src/servo/dom/bindings/utils.rs +++ b/src/servo/dom/bindings/utils.rs @@ -6,11 +6,11 @@ import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_Re JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate, JS_GetClass, JS_GetPrototype}; +import js::crust::{JS_ConvertStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub}; import js::glue::bindgen::*; import ptr::null; import result::{result, ok, err}; -import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, - JS_ResolveStub, JS_ConvertStub}; enum DOMString { str(~str), @@ -95,8 +95,37 @@ extern fn has_instance(_cx: *JSContext, obj: *JSObject, v: *jsval, bp: *mut JSBo return 1; } -fn Document_class(compartment: bare_compartment, name: ~str, - finalize: *u8) -> JSClass { +fn prototype_jsclass(name: ~str) -> fn(bare_compartment) -> JSClass { + return fn@(compartment: bare_compartment) -> JSClass { + {name: compartment.add_name(name), + flags: 0, + addProperty: JS_PropertyStub, + delProperty: JS_PropertyStub, + getProperty: JS_PropertyStub, + setProperty: JS_StrictPropertyStub, + enumerate: JS_EnumerateStub, + resolve: JS_PropertyStub, + convert: JS_ConvertStub, + finalize: null(), + checkAccess: null(), + call: null(), + construct: null(), + hasInstance: has_instance, + trace: null(), + reserved: (null(), null(), null(), null(), null(), // 05 + null(), null(), null(), null(), null(), // 10 + null(), null(), null(), null(), null(), // 15 + null(), null(), null(), null(), null(), // 20 + null(), null(), null(), null(), null(), // 25 + null(), null(), null(), null(), null(), // 30 + null(), null(), null(), null(), null(), // 35 + null(), null(), null(), null(), null())} // 40 + }; +} + +fn instance_jsclass(name: ~str, finalize: *u8) + -> fn(bare_compartment) -> JSClass { + return fn@(compartment: bare_compartment) -> JSClass { {name: compartment.add_name(name), flags: JSCLASS_HAS_RESERVED_SLOTS(1), addProperty: JS_PropertyStub, @@ -110,7 +139,7 @@ fn Document_class(compartment: bare_compartment, name: ~str, checkAccess: null(), call: null(), construct: null(), - hasInstance: null(), + hasInstance: has_instance, trace: null(), reserved: (null(), null(), null(), null(), null(), // 05 null(), null(), null(), null(), null(), // 10 @@ -120,4 +149,24 @@ fn Document_class(compartment: bare_compartment, name: ~str, null(), null(), null(), null(), null(), // 30 null(), null(), null(), null(), null(), // 35 null(), null(), null(), null(), null())} // 40 + }; +} + +fn define_empty_prototype(name: ~str, proto: option<~str>, compartment: bare_compartment) + -> js::rust::jsobj { + compartment.register_class(utils::prototype_jsclass(name)); + + //TODO error checking + let obj = result::unwrap( + match proto { + some(s) => compartment.new_object_with_proto(name, s, + compartment.global_obj.ptr), + none => compartment.new_object(name, null(), compartment.global_obj.ptr) + }); + + compartment.define_property(name, RUST_OBJECT_TO_JSVAL(obj.ptr), + JS_PropertyStub, JS_StrictPropertyStub, + JSPROP_ENUMERATE); + compartment.stash_global_proto(name, obj); + return obj; } diff --git a/src/servo/dom/bindings/window.rs b/src/servo/dom/bindings/window.rs index 646d872b623..2c9f4b15c51 100644 --- a/src/servo/dom/bindings/window.rs +++ b/src/servo/dom/bindings/window.rs @@ -11,17 +11,10 @@ import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ import result::{result, ok, err}; import ptr::null; import libc::c_uint; -import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str, - Document_class}; +import utils::{rust_box, squirrel_away, jsval_to_str}; import bindings::node::create; import base::{Node, Window}; -enum DOMException { - INVALID_CHARACTER_ERR -} - -enum Element = int; - extern fn alert(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool { unsafe { let argv = JS_ARGV(cx, vp); @@ -35,15 +28,6 @@ extern fn alert(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool { 1_i32 } -// Unfortunately duplicated in document and window. -// Generalizing it triggers a trans bug -extern fn getDocumentElement(cx: *JSContext, obj: *JSObject, - _id: jsid, rval: *mut jsval) -> JSBool unsafe { - let node = (*unwrap(obj)).payload.root; - *rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr); - return 1; -} - unsafe fn unwrap(obj: *JSObject) -> *rust_box { let val = JS_GetReservedSlot(obj, 0); unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val)) @@ -58,12 +42,12 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { } fn init(compartment: bare_compartment, win: @Window) { - - compartment.register_class(|c| Document_class(c, ~"DOMWindow", - finalize)); + let proto = utils::define_empty_prototype(~"Window", none, compartment); + compartment.register_class(utils::instance_jsclass(~"WindowInstance", finalize)); let obj = result::unwrap( - compartment.new_object(~"DOMWindow", null(), null())); + compartment.new_object_with_proto(~"WindowInstance", + ~"Window", null())); /* Define methods on a window */ let methods = ~[{name: compartment.add_name(~"alert"), @@ -72,25 +56,16 @@ fn init(compartment: bare_compartment, win: @Window) { flags: 0}]; vec::as_buf(methods, |fns, _len| { - JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns); + JS_DefineFunctions(compartment.cx.ptr, proto.ptr, fns); }); - let attrs = @~[ - {name: compartment.add_name(~"DOMWindow"), - tinyid: 0, // ??? - flags: 0, - getter: getDocumentElement, - setter: null()}]; - vec::push(compartment.global_props, attrs); - vec::as_buf(*attrs, |specs, _len| { - JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); - }); - unsafe { let raw_ptr: *libc::c_void = unsafe::reinterpret_cast(squirrel_away(win)); JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); } + //TODO: All properties/methods on Window need to be available on the global + // object as well. We probably want a special JSClass with a resolve hook. compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr), JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE); diff --git a/src/servo/gfx/geometry.rs b/src/servo/gfx/geometry.rs index 731c8ee50f2..ad03b229bf2 100644 --- a/src/servo/gfx/geometry.rs +++ b/src/servo/gfx/geometry.rs @@ -1,9 +1,9 @@ import geom::point::Point2D; import geom::rect::Rect; import geom::size::Size2D; -import num::Num; +import num::{Num, from_int}; -enum au = int; +enum au = i32; impl au : Num { pure fn add(&&other: au) -> au { au(*self + *other) } @@ -13,8 +13,10 @@ impl au : Num { pure fn modulo(&&other: au) -> au { au(*self % *other) } pure fn neg() -> au { au(-*self) } - pure fn to_int() -> int { *self } - static pure fn from_int(n: int) -> au { au(n) } + pure fn to_int() -> int { *self as int } + static pure fn from_int(n: int) -> au { + au((n & (i32::max_value as int)) as i32) + } } fn box(x: A, y: A, w: A, h: A) -> Rect { @@ -31,9 +33,9 @@ fn zero_size_au() -> Size2D { } pure fn px_to_au(i: int) -> au { - au(i * 60) + from_int(i * 60) } pure fn au_to_px(au: au) -> int { - *au / 60 + (*au / 60) as int } diff --git a/src/servo/layout/inline.rs b/src/servo/layout/inline.rs index bb1d8e19155..d3b6e8e5583 100644 --- a/src/servo/layout/inline.rs +++ b/src/servo/layout/inline.rs @@ -30,7 +30,7 @@ impl @Box : InlineLayout { for tree::each_child(BTree, self) |kid| { kid.bounds.origin = Point2D(au(x), au(y)); x += *kid.bounds.size.width; - current_height = int::max(current_height, *kid.bounds.size.height); + current_height = i32::max(current_height, *kid.bounds.size.height); } let height = match self.appearance.height { @@ -41,7 +41,7 @@ impl @Box : InlineLayout { let width = match self.appearance.width { Px(p) => px_to_au(p.to_int()), - Auto => au(int::max(x, *self.bounds.size.width)), + Auto => au(i32::max(x, *self.bounds.size.width)), _ => fail ~"inhereit_width failed, width is neither a Px or auto" }; diff --git a/src/servo/servo.rc b/src/servo/servo.rc index 4b11b2d472e..5c6f5e2ecd5 100755 --- a/src/servo/servo.rc +++ b/src/servo/servo.rc @@ -26,6 +26,7 @@ mod dom { mod style; mod bindings { mod document; + mod element; mod utils; mod node; mod window; diff --git a/src/test/test-js-image.html b/src/test/test-js-image.html new file mode 100644 index 00000000000..4d899bb9e21 --- /dev/null +++ b/src/test/test-js-image.html @@ -0,0 +1,3 @@ + + + diff --git a/src/test/test_image_getter.js b/src/test/test_image_getter.js new file mode 100644 index 00000000000..55ba55f3ce8 --- /dev/null +++ b/src/test/test_image_getter.js @@ -0,0 +1,6 @@ +var elem = document.documentElement.firstChild; +debug(elem.tagName); +debug(elem instanceof HTMLImageElement); +debug(elem.width); +elem.width = 1000; +debug(elem.width);