mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add further HMTL element prototype hierarchy. Add HTMLImageElement.width getter/setter that interacts with layout.
This commit is contained in:
parent
bfec29d86f
commit
07c17fdef4
13 changed files with 250 additions and 211 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02
|
||||
Subproject commit 9bf630c5f2035a29e7ccee0ca94e9c4568815f7b
|
|
@ -136,7 +136,7 @@ struct Content<C:Compositor> {
|
|||
#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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
145
src/servo/dom/bindings/element.rs
Normal file
145
src/servo/dom/bindings/element.rs
Normal file
|
@ -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;
|
||||
}
|
|
@ -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<Node> {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<Window> {
|
||||
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);
|
||||
|
|
|
@ -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<A:copy Num>(x: A, y: A, w: A, h: A) -> Rect<A> {
|
||||
|
@ -31,9 +33,9 @@ fn zero_size_au() -> Size2D<au> {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ mod dom {
|
|||
mod style;
|
||||
mod bindings {
|
||||
mod document;
|
||||
mod element;
|
||||
mod utils;
|
||||
mod node;
|
||||
mod window;
|
||||
|
|
3
src/test/test-js-image.html
Normal file
3
src/test/test-js-image.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<img src="test.jpeg" width="50" height="378"/>
|
||||
<script src="test_image_getter.js"></script>
|
||||
|
6
src/test/test_image_getter.js
Normal file
6
src/test/test_image_getter.js
Normal file
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue