mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Merge remote-tracking branch 'origin/master'
Conflicts: src/components/script/dom/bindings/element.rs src/components/script/dom/bindings/node.rs src/components/script/dom/bindings/utils.rs
This commit is contained in:
commit
4487b1c29a
10 changed files with 25 additions and 546 deletions
|
@ -599,6 +599,10 @@ impl RenderBox {
|
||||||
match *self {
|
match *self {
|
||||||
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here."),
|
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here."),
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
|
|
||||||
|
// Add the background to the list, if applicable.
|
||||||
|
self.paint_background_if_applicable(list, &absolute_box_bounds);
|
||||||
|
|
||||||
let nearest_ancestor_element = self.nearest_ancestor_element();
|
let nearest_ancestor_element = self.nearest_ancestor_element();
|
||||||
let color = nearest_ancestor_element.style().color().to_gfx_color();
|
let color = nearest_ancestor_element.style().color().to_gfx_color();
|
||||||
|
|
||||||
|
|
|
@ -4,314 +4,10 @@
|
||||||
|
|
||||||
use dom::types::*;
|
use dom::types::*;
|
||||||
use dom::bindings::codegen::*;
|
use dom::bindings::codegen::*;
|
||||||
use dom::bindings::node::unwrap;
|
use dom::bindings::utils::{BindingObject, WrapperCache, CacheableWrapper};
|
||||||
use dom::bindings::utils::jsval_to_str;
|
use dom::node::ScriptView;
|
||||||
use dom::bindings::utils::{domstring_to_jsval, WrapNewBindingObject};
|
|
||||||
use dom::bindings::utils::{str, CacheableWrapper, DOM_OBJECT_SLOT, DOMString};
|
|
||||||
use dom::bindings::utils::{BindingObject, WrapperCache};
|
|
||||||
use dom::element::Element;
|
|
||||||
use dom::element::{HTMLImageElementTypeId, HTMLHeadElementTypeId, HTMLScriptElementTypeId,
|
|
||||||
HTMLDivElementTypeId};
|
|
||||||
use dom::node::{AbstractNode, ScriptView, ElementNodeTypeId};
|
|
||||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
|
||||||
use script_task::page_from_context;
|
|
||||||
use super::utils;
|
|
||||||
|
|
||||||
use std::cast;
|
use js::jsapi::{JSContext, JSObject};
|
||||||
use std::i32;
|
|
||||||
use std::libc;
|
|
||||||
use std::libc::c_uint;
|
|
||||||
use std::comm;
|
|
||||||
use std::ptr;
|
|
||||||
use std::ptr::null;
|
|
||||||
use js::glue::*;
|
|
||||||
use js::jsapi::*;
|
|
||||||
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};
|
|
||||||
use js::{JS_THIS_OBJECT, JSPROP_NATIVE_ACCESSORS};
|
|
||||||
|
|
||||||
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
|
||||||
debug!("element finalize: %x!", obj as uint);
|
|
||||||
unsafe {
|
|
||||||
let node: AbstractNode<ScriptView> = unwrap(obj);
|
|
||||||
//XXXjdm We need separate finalizers for each specialty element type like headings
|
|
||||||
let _elem: @Element = cast::transmute(node.raw_object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn trace(tracer: *mut JSTracer, obj: *JSObject) {
|
|
||||||
let node = unsafe { unwrap(obj) };
|
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode<ScriptView>>, name: &str) {
|
|
||||||
if node.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
error!("tracing %s", name);
|
|
||||||
let mut node = node.unwrap();
|
|
||||||
let cache = node.get_wrappercache();
|
|
||||||
let wrapper = cache.get_wrapper();
|
|
||||||
assert!(wrapper.is_not_null());
|
|
||||||
unsafe {
|
|
||||||
(*tracer).debugPrinter = ptr::null();
|
|
||||||
(*tracer).debugPrintIndex = -1;
|
|
||||||
do name.to_c_str().with_ref |name| {
|
|
||||||
(*tracer).debugPrintArg = name as *libc::c_void;
|
|
||||||
JS_CallTracer(cast::transmute(tracer), wrapper, JSTRACE_OBJECT as u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error!("tracing %?:", obj as uint);
|
|
||||||
trace_node(tracer, node.parent_node(), "parent");
|
|
||||||
trace_node(tracer, node.first_child(), "first child");
|
|
||||||
trace_node(tracer, node.last_child(), "last child");
|
|
||||||
trace_node(tracer, node.next_sibling(), "next sibling");
|
|
||||||
trace_node(tracer, node.prev_sibling(), "prev sibling");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
pub fn init(compartment: @mut Compartment) {
|
|
||||||
let obj = utils::define_empty_prototype(~"Element", Some(~"Node"), compartment);
|
|
||||||
let attrs = @~[
|
|
||||||
JSPropertySpec {
|
|
||||||
name: compartment.add_name(~"tagName"),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: Some(getTagName), info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}},
|
|
||||||
JSPropertySpec {
|
|
||||||
name: null(),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: None, info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}}];
|
|
||||||
compartment.global_props.push(attrs);
|
|
||||||
do attrs.as_imm_buf |specs, _len| {
|
|
||||||
unsafe {
|
|
||||||
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getClientRects"),
|
|
||||||
call: JSNativeWrapper {op: Some(getClientRects), info: null()},
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()},
|
|
||||||
JSFunctionSpec {name: compartment.add_name(~"getBoundingClientRect"),
|
|
||||||
call: JSNativeWrapper {op: Some(getBoundingClientRect), info: null()},
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()},
|
|
||||||
JSFunctionSpec {name: compartment.add_name(~"setAttribute"),
|
|
||||||
call: JSNativeWrapper {op: Some(setAttribute), info: null()},
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()},
|
|
||||||
JSFunctionSpec {name: null(),
|
|
||||||
call: JSNativeWrapper {op: None, info: null()},
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()}];
|
|
||||||
do methods.as_imm_buf |fns, _len| {
|
|
||||||
unsafe {
|
|
||||||
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compartment.register_class(utils::instance_jsclass(~"GenericElementInstance",
|
|
||||||
finalize, trace));
|
|
||||||
|
|
||||||
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 = @~[
|
|
||||||
JSPropertySpec {name: compartment.add_name(~"width"),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: Some(HTMLImageElement_getWidth), info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: Some(HTMLImageElement_setWidth), info: null()}},
|
|
||||||
JSPropertySpec {name: null(),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: None, info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}}];
|
|
||||||
compartment.global_props.push(attrs);
|
|
||||||
do attrs.as_imm_buf |specs, _len| {
|
|
||||||
unsafe {
|
|
||||||
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getClientRects(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
let mut node = unwrap(obj);
|
|
||||||
let rval = do node.with_imm_element |elem| {
|
|
||||||
elem.GetClientRects(node)
|
|
||||||
};
|
|
||||||
let cache = node.get_wrappercache();
|
|
||||||
let rval = rval as @mut CacheableWrapper;
|
|
||||||
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
|
|
||||||
rval,
|
|
||||||
cast::transmute(vp)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getBoundingClientRect(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
let mut node = unwrap(obj);
|
|
||||||
let rval = do node.with_imm_element |elem| {
|
|
||||||
elem.GetBoundingClientRect(node)
|
|
||||||
};
|
|
||||||
let cache = node.get_wrappercache();
|
|
||||||
let rval = rval as @mut CacheableWrapper;
|
|
||||||
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
|
|
||||||
rval,
|
|
||||||
cast::transmute(vp)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn setAttribute(cx: *JSContext, argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
let node = unwrap(obj);
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
return 0; //XXXjdm throw exception
|
|
||||||
}
|
|
||||||
|
|
||||||
let argv = JS_ARGV(cx, cast::transmute(vp));
|
|
||||||
|
|
||||||
let arg0: DOMString;
|
|
||||||
let strval = jsval_to_str(cx, (*argv.offset(0)));
|
|
||||||
if strval.is_err() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
arg0 = str(strval.unwrap());
|
|
||||||
|
|
||||||
let arg1: DOMString;
|
|
||||||
let strval = jsval_to_str(cx, (*argv.offset(1)));
|
|
||||||
if strval.is_err() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
arg1 = str(strval.unwrap());
|
|
||||||
|
|
||||||
do node.as_mut_element |elem| {
|
|
||||||
elem.set_attr(&arg0, &arg1);
|
|
||||||
};
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn HTMLImageElement_getWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
let width = match node.type_id() {
|
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
|
||||||
let page = page_from_context(cx);
|
|
||||||
let (port, chan) = comm::stream();
|
|
||||||
// TODO(tkuehn): currently this just queries top-level page's layout. Need to handle subframes.
|
|
||||||
match (*page).query_layout(ContentBoxQuery(node, chan), port) {
|
|
||||||
Ok(ContentBoxResponse(rect)) => rect.size.width.to_nearest_px(),
|
|
||||||
Err(()) => 0
|
|
||||||
}
|
|
||||||
// TODO: if nothing is being rendered(?), return zero dimensions
|
|
||||||
}
|
|
||||||
ElementNodeTypeId(_) => fail!(~"why is this not an image element?"),
|
|
||||||
_ => fail!(~"why is this not an element?")
|
|
||||||
};
|
|
||||||
|
|
||||||
*vp = RUST_INT_TO_JSVAL(
|
|
||||||
(width & (i32::max_value as int)) as libc::c_int);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn HTMLImageElement_setWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
match node.type_id() {
|
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
|
||||||
do node.as_mut_element |elem| {
|
|
||||||
let arg = ptr::offset(JS_ARGV(cx, cast::transmute(vp)), 0);
|
|
||||||
elem.set_attr(&str(~"width"),
|
|
||||||
&str((RUST_JSVAL_TO_INT(*arg) as int).to_str()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ElementNodeTypeId(_) => fail!(~"why is this not an image element?"),
|
|
||||||
_ => fail!(~"why is this not an element?")
|
|
||||||
};
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getTagName(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
do node.with_imm_element |elem| {
|
|
||||||
let s = str(elem.tag_name.clone());
|
|
||||||
*vp = domstring_to_jsval(cx, &s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> jsobj {
|
|
||||||
let proto = match node.type_id() {
|
|
||||||
ElementNodeTypeId(HTMLDivElementTypeId) => ~"HTMLDivElement",
|
|
||||||
ElementNodeTypeId(HTMLHeadElementTypeId) => ~"HTMLHeadElement",
|
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => ~"HTMLImageElement",
|
|
||||||
ElementNodeTypeId(HTMLScriptElementTypeId) => ~"HTMLScriptElement",
|
|
||||||
ElementNodeTypeId(_) => ~"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 = compartment.new_object_with_proto(~"GenericElementInstance",
|
|
||||||
proto,
|
|
||||||
compartment.global_obj.ptr).unwrap();
|
|
||||||
|
|
||||||
let cache = node.get_wrappercache();
|
|
||||||
assert!(cache.get_wrapper().is_null());
|
|
||||||
cache.set_wrapper(obj.ptr);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let raw_ptr = node.raw_object() as *libc::c_void;
|
|
||||||
JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT as u32, RUST_PRIVATE_TO_JSVAL(raw_ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub macro_rules! generate_cacheable_wrapper(
|
pub macro_rules! generate_cacheable_wrapper(
|
||||||
($name: path, $wrap: path) => (
|
($name: path, $wrap: path) => (
|
||||||
|
|
|
@ -2,67 +2,17 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::element;
|
use dom::bindings::utils::{CacheableWrapper, WrapperCache};
|
||||||
use dom::bindings::utils;
|
|
||||||
use dom::bindings::utils::{CacheableWrapper, WrapperCache, DerivedWrapper};
|
|
||||||
use dom::element::*;
|
use dom::element::*;
|
||||||
use dom::types::*;
|
use dom::types::*;
|
||||||
use dom::node::{AbstractNode, Node, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
|
use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
|
||||||
use dom::node::{DoctypeNodeTypeId, ScriptView};
|
use dom::node::{DoctypeNodeTypeId, ScriptView};
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::libc::c_uint;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::null;
|
use js::jsapi::{JSContext, JSObject};
|
||||||
use js::jsapi::*;
|
|
||||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSPropertySpec};
|
|
||||||
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper};
|
|
||||||
use js::jsval::{INT_TO_JSVAL};
|
|
||||||
use js::rust::{Compartment};
|
|
||||||
use js::{JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
|
|
||||||
use js::{JS_THIS_OBJECT, JSPROP_NATIVE_ACCESSORS};
|
|
||||||
use servo_util::tree::TreeNodeRef;
|
use servo_util::tree::TreeNodeRef;
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
pub fn init(compartment: @mut Compartment) {
|
|
||||||
let obj = utils::define_empty_prototype(~"Node", None, compartment);
|
|
||||||
|
|
||||||
let attrs = @~[
|
|
||||||
JSPropertySpec {
|
|
||||||
name: compartment.add_name(~"firstChild"),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: Some(getFirstChild), info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}},
|
|
||||||
|
|
||||||
JSPropertySpec {
|
|
||||||
name: compartment.add_name(~"nextSibling"),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: Some(getNextSibling), info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}},
|
|
||||||
|
|
||||||
JSPropertySpec {
|
|
||||||
name: compartment.add_name(~"nodeType"),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: Some(getNodeType), info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}},
|
|
||||||
|
|
||||||
JSPropertySpec {
|
|
||||||
name: null(),
|
|
||||||
tinyid: 0,
|
|
||||||
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
|
|
||||||
getter: JSPropertyOpWrapper {op: None, info: null()},
|
|
||||||
setter: JSStrictPropertyOpWrapper {op: None, info: null()}}];
|
|
||||||
compartment.global_props.push(attrs);
|
|
||||||
do attrs.as_imm_buf |specs, _len| {
|
|
||||||
unsafe {
|
|
||||||
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! generate_element(
|
macro_rules! generate_element(
|
||||||
($name: path) => ({
|
($name: path) => ({
|
||||||
let node: @mut $name = unsafe { cast::transmute(node.raw_object()) };
|
let node: @mut $name = unsafe { cast::transmute(node.raw_object()) };
|
||||||
|
@ -130,76 +80,12 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject
|
||||||
ElementNodeTypeId(HTMLTitleElementTypeId) => generate_element!(HTMLTitleElement),
|
ElementNodeTypeId(HTMLTitleElementTypeId) => generate_element!(HTMLTitleElement),
|
||||||
ElementNodeTypeId(HTMLUListElementTypeId) => generate_element!(HTMLUListElement),
|
ElementNodeTypeId(HTMLUListElementTypeId) => generate_element!(HTMLUListElement),
|
||||||
ElementNodeTypeId(HTMLUnknownElementTypeId) => generate_element!(HTMLUnknownElement),
|
ElementNodeTypeId(HTMLUnknownElementTypeId) => generate_element!(HTMLUnknownElement),
|
||||||
ElementNodeTypeId(_) => element::create(cx, node).ptr,
|
|
||||||
CommentNodeTypeId => generate_element!(Comment),
|
CommentNodeTypeId => generate_element!(Comment),
|
||||||
DoctypeNodeTypeId => generate_element!(DocumentType<ScriptView>),
|
DoctypeNodeTypeId => generate_element!(DocumentType<ScriptView>),
|
||||||
TextNodeTypeId => generate_element!(Text)
|
TextNodeTypeId => generate_element!(Text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn unwrap(obj: *JSObject) -> AbstractNode<ScriptView> {
|
|
||||||
let raw = utils::unwrap::<*mut Node<ScriptView>>(obj);
|
|
||||||
AbstractNode::from_raw(raw)
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getFirstChild(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
let rval = do node.with_mut_base |base| {
|
|
||||||
base.getFirstChild()
|
|
||||||
};
|
|
||||||
match rval {
|
|
||||||
Some(n) => {
|
|
||||||
n.wrap(cx, ptr::null(), vp); //XXXjdm pass a real scope
|
|
||||||
}
|
|
||||||
None => *vp = JSVAL_NULL
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getNextSibling(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
let rval = do node.with_mut_base |base| {
|
|
||||||
base.getNextSibling()
|
|
||||||
};
|
|
||||||
match rval {
|
|
||||||
Some(n) => {
|
|
||||||
n.wrap(cx, ptr::null(), vp); //XXXjdm pass a real scope
|
|
||||||
}
|
|
||||||
None => *vp = JSVAL_NULL
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn getNodeType(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let obj = JS_THIS_OBJECT(cx, cast::transmute(vp));
|
|
||||||
if obj.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = unwrap(obj);
|
|
||||||
let rval = do node.with_base |base| {
|
|
||||||
base.getNodeType()
|
|
||||||
};
|
|
||||||
*vp = INT_TO_JSVAL(rval);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CacheableWrapper for AbstractNode<ScriptView> {
|
impl CacheableWrapper for AbstractNode<ScriptView> {
|
||||||
fn get_wrappercache(&mut self) -> &mut WrapperCache {
|
fn get_wrappercache(&mut self) -> &mut WrapperCache {
|
||||||
do self.with_mut_base |base| {
|
do self.with_mut_base |base| {
|
||||||
|
|
|
@ -20,7 +20,6 @@ use std::unstable::intrinsics;
|
||||||
use js::glue::*;
|
use js::glue::*;
|
||||||
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
|
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
|
||||||
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
||||||
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB};
|
|
||||||
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction, JS_GetGlobalObject};
|
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction, JS_GetGlobalObject};
|
||||||
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
|
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
|
||||||
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
|
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
|
||||||
|
@ -35,7 +34,7 @@ use js::jsapi::{JSFreeOp, JSTracer};
|
||||||
use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JSEnumerateOp, JSResolveOp, JSConvertOp};
|
use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JSEnumerateOp, JSResolveOp, JSConvertOp};
|
||||||
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
||||||
use js::rust::Compartment;
|
use js::rust::Compartment;
|
||||||
use js::{JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSVAL_NULL};
|
use js::{JSPROP_ENUMERATE, JSVAL_NULL};
|
||||||
use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER};
|
use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER};
|
||||||
use js::{JSPROP_SETTER, JSVAL_VOID, JSVAL_TRUE, JSVAL_FALSE};
|
use js::{JSPROP_SETTER, JSVAL_VOID, JSVAL_TRUE, JSVAL_FALSE};
|
||||||
use js::{JS_THIS_OBJECT, JSFUN_CONSTRUCTOR, JS_CALLEE, JSPROP_READONLY};
|
use js::{JS_THIS_OBJECT, JSFUN_CONSTRUCTOR, JS_CALLEE, JSPROP_READONLY};
|
||||||
|
@ -258,114 +257,6 @@ extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass {
|
|
||||||
let name = Cell::new(name);
|
|
||||||
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
|
|
||||||
let name = name.take();
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
fn just_effin_do_it(name: ~str, compartment: @mut Compartment) -> JSClass {
|
|
||||||
unsafe {
|
|
||||||
JSClass {
|
|
||||||
name: compartment.add_name(name.to_owned()),
|
|
||||||
flags: 0,
|
|
||||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as JSStrictPropertyOp,
|
|
||||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as JSEnumerateOp,
|
|
||||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as JSResolveOp,
|
|
||||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as JSConvertOp,
|
|
||||||
finalize: None,
|
|
||||||
checkAccess: None,
|
|
||||||
call: None,
|
|
||||||
hasInstance: Some(has_instance),
|
|
||||||
construct: None,
|
|
||||||
trace: None,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
just_effin_do_it(name, compartment)
|
|
||||||
};
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn instance_jsclass(name: ~str, finalize: extern "C" fn(*JSFreeOp, *JSObject),
|
|
||||||
trace: extern "C" fn(*mut JSTracer, *JSObject))
|
|
||||||
-> @fn(compartment: @mut Compartment) -> JSClass {
|
|
||||||
let name = Cell::new(name);
|
|
||||||
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
|
|
||||||
let name = name.take();
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
fn just_effin_do_it(name: ~str, finalize: extern "C" fn(*JSFreeOp, *JSObject),
|
|
||||||
trace: extern "C" fn(*mut JSTracer, *JSObject),
|
|
||||||
compartment: @mut Compartment) -> JSClass {
|
|
||||||
unsafe {
|
|
||||||
JSClass {
|
|
||||||
name: compartment.add_name(name.to_owned()),
|
|
||||||
flags: JSCLASS_HAS_RESERVED_SLOTS(1) | js::JSCLASS_IS_DOMJSCLASS,
|
|
||||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as JSStrictPropertyOp,
|
|
||||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as JSEnumerateOp,
|
|
||||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as JSResolveOp,
|
|
||||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as JSConvertOp,
|
|
||||||
finalize: Some(finalize),
|
|
||||||
checkAccess: None,
|
|
||||||
call: None,
|
|
||||||
hasInstance: Some(has_instance),
|
|
||||||
construct: None,
|
|
||||||
trace: Some(trace),
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
just_effin_do_it(name, finalize, trace, compartment)
|
|
||||||
};
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
|
||||||
pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut Compartment)
|
|
||||||
-> js::rust::jsobj {
|
|
||||||
compartment.register_class(prototype_jsclass(name.to_owned()));
|
|
||||||
|
|
||||||
//TODO error checking
|
|
||||||
let obj = (
|
|
||||||
match proto {
|
|
||||||
Some(s) => compartment.new_object_with_proto(name.to_owned(),
|
|
||||||
s,
|
|
||||||
compartment.global_obj.ptr),
|
|
||||||
None => compartment.new_object(name.to_owned(), null(), compartment.global_obj.ptr)
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
compartment.define_property(name.to_owned(), RUST_OBJECT_TO_JSVAL(obj.ptr),
|
|
||||||
GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp,
|
|
||||||
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as JSStrictPropertyOp,
|
|
||||||
JSPROP_ENUMERATE);
|
|
||||||
compartment.stash_global_proto(name, obj);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We use slot 0 for holding the raw object. This is safe for both
|
// We use slot 0 for holding the raw object. This is safe for both
|
||||||
// globals and non-globals.
|
// globals and non-globals.
|
||||||
pub static DOM_OBJECT_SLOT: uint = 0;
|
pub static DOM_OBJECT_SLOT: uint = 0;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
use dom::bindings::utils::{null_string, str};
|
use dom::bindings::utils::{null_string, str};
|
||||||
use dom::bindings::utils::{BindingObject, CacheableWrapper, DOMString, ErrorResult, WrapperCache};
|
use dom::bindings::utils::{BindingObject, CacheableWrapper, DOMString, ErrorResult, WrapperCache};
|
||||||
use dom::htmlelement::HTMLElement;
|
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::HTMLCollection;
|
||||||
use dom::clientrect::ClientRect;
|
use dom::clientrect::ClientRect;
|
||||||
use dom::clientrectlist::ClientRectList;
|
use dom::clientrectlist::ClientRectList;
|
||||||
|
@ -91,7 +90,6 @@ pub enum ElementTypeId {
|
||||||
HTMLQuoteElementTypeId,
|
HTMLQuoteElementTypeId,
|
||||||
HTMLScriptElementTypeId,
|
HTMLScriptElementTypeId,
|
||||||
HTMLSelectElementTypeId,
|
HTMLSelectElementTypeId,
|
||||||
HTMLSmallElementTypeId,
|
|
||||||
HTMLSourceElementTypeId,
|
HTMLSourceElementTypeId,
|
||||||
HTMLSpanElementTypeId,
|
HTMLSpanElementTypeId,
|
||||||
HTMLStyleElementTypeId,
|
HTMLStyleElementTypeId,
|
||||||
|
@ -108,12 +106,6 @@ pub enum ElementTypeId {
|
||||||
HTMLUnknownElementTypeId,
|
HTMLUnknownElementTypeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Regular old elements
|
|
||||||
//
|
|
||||||
|
|
||||||
pub struct HTMLSmallElement { parent: HTMLElement }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Element methods
|
// Element methods
|
||||||
//
|
//
|
||||||
|
|
|
@ -608,8 +608,6 @@ impl VoidPtrLike for AbstractNode<LayoutView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define_bindings(compartment: @mut Compartment) {
|
pub fn define_bindings(compartment: @mut Compartment) {
|
||||||
bindings::node::init(compartment);
|
|
||||||
bindings::element::init(compartment);
|
|
||||||
bindings::utils::initialize_global(compartment.global_obj.ptr);
|
bindings::utils::initialize_global(compartment.global_obj.ptr);
|
||||||
bindings::codegen::RegisterBindings::Register(compartment);
|
bindings::codegen::RegisterBindings::Register(compartment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,6 @@ fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptView>
|
||||||
handle_element!(cx, tag, "q", HTMLQuoteElementTypeId, HTMLQuoteElement, []);
|
handle_element!(cx, tag, "q", HTMLQuoteElementTypeId, HTMLQuoteElement, []);
|
||||||
handle_element!(cx, tag, "script", HTMLScriptElementTypeId, HTMLScriptElement, []);
|
handle_element!(cx, tag, "script", HTMLScriptElementTypeId, HTMLScriptElement, []);
|
||||||
handle_element!(cx, tag, "select", HTMLSelectElementTypeId, HTMLSelectElement, []);
|
handle_element!(cx, tag, "select", HTMLSelectElementTypeId, HTMLSelectElement, []);
|
||||||
handle_element!(cx, tag, "small", HTMLSmallElementTypeId, HTMLSmallElement, []);
|
|
||||||
handle_element!(cx, tag, "source", HTMLSourceElementTypeId, HTMLSourceElement, []);
|
handle_element!(cx, tag, "source", HTMLSourceElementTypeId, HTMLSourceElement, []);
|
||||||
handle_element!(cx, tag, "span", HTMLSpanElementTypeId, HTMLSpanElement, []);
|
handle_element!(cx, tag, "span", HTMLSpanElementTypeId, HTMLSpanElement, []);
|
||||||
handle_element!(cx, tag, "style", HTMLStyleElementTypeId, HTMLStyleElement, []);
|
handle_element!(cx, tag, "style", HTMLStyleElementTypeId, HTMLStyleElement, []);
|
||||||
|
@ -256,6 +255,7 @@ fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptView>
|
||||||
handle_htmlelement!(cx, tag, "b", HTMLElementTypeId, HTMLElement);
|
handle_htmlelement!(cx, tag, "b", HTMLElementTypeId, HTMLElement);
|
||||||
handle_htmlelement!(cx, tag, "i", HTMLElementTypeId, HTMLElement);
|
handle_htmlelement!(cx, tag, "i", HTMLElementTypeId, HTMLElement);
|
||||||
handle_htmlelement!(cx, tag, "section", HTMLElementTypeId, HTMLElement);
|
handle_htmlelement!(cx, tag, "section", HTMLElementTypeId, HTMLElement);
|
||||||
|
handle_htmlelement!(cx, tag, "small", HTMLElementTypeId, HTMLElement);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let element = @HTMLUnknownElement {
|
let element = @HTMLUnknownElement {
|
||||||
|
|
11
src/test/html/inline_bg_color_simple.html
Normal file
11
src/test/html/inline_bg_color_simple.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
[block background color test]
|
||||||
|
<p style="background-color:yellow">paragraph yellow</p>
|
||||||
|
|
||||||
|
[inline background color test]
|
||||||
|
<span style="background-color:blue;">span blue</span>texttexttext<span style="background-color:yellow;">span yellow<span style="background-color:red">nested-span red</span>test finishes</span>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -41,6 +41,7 @@
|
||||||
<aside>aside</aside>
|
<aside>aside</aside>
|
||||||
<b>b</b>
|
<b>b</b>
|
||||||
<i>i</i>
|
<i>i</i>
|
||||||
|
<small>small</small>
|
||||||
<textarea>textarea</textarea>
|
<textarea>textarea</textarea>
|
||||||
<time datetime="2014-02-14">Valentines day</time>
|
<time datetime="2014-02-14">Valentines day</time>
|
||||||
<audio>
|
<audio>
|
||||||
|
|
|
@ -145,7 +145,7 @@ window.alert(tags[0]);
|
||||||
window.alert(tags[0].tagName);
|
window.alert(tags[0].tagName);
|
||||||
|
|
||||||
window.alert("HTMLElement:");
|
window.alert("HTMLElement:");
|
||||||
let tagList = ["section", "aside", "b", "i"];
|
let tagList = ["section", "aside", "b", "i", "small"];
|
||||||
for (let i = 0, l = tagList.length; i < l; ++i) {
|
for (let i = 0, l = tagList.length; i < l; ++i) {
|
||||||
let tags = document.getElementsByTagName(tagList[i]);
|
let tags = document.getElementsByTagName(tagList[i]);
|
||||||
window.alert(tags);
|
window.alert(tags);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue