aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/node.rs
blob: d1f60eb21e8e3defb5e32431379d4d787dc70ab1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* 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/. */

use dom::bindings::utils::{Reflectable, Reflector, Traceable};
use dom::element::*;
use dom::types::*;
use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
use dom::node::{DoctypeNodeTypeId, ScriptView};

use std::cast;
use std::libc;
use std::ptr;
use js::jsapi::{JSContext, JSObject, JSTracer, JSTRACE_OBJECT, JS_CallTracer};
use servo_util::tree::TreeNodeRef;

macro_rules! generate_element(
    ($name: path) => ({
        let node: @mut $name = unsafe { cast::transmute(node.raw_object()) };
        node.wrap_object_shared(cx, ptr::null())
    })
)

pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject {
    match node.type_id() {
        ElementNodeTypeId(HTMLElementTypeId) => generate_element!(HTMLElement),
        ElementNodeTypeId(HTMLAnchorElementTypeId) => generate_element!(HTMLAnchorElement),
        ElementNodeTypeId(HTMLAppletElementTypeId) => generate_element!(HTMLAppletElement),
        ElementNodeTypeId(HTMLAreaElementTypeId) => generate_element!(HTMLAreaElement),
        ElementNodeTypeId(HTMLAudioElementTypeId) => generate_element!(HTMLAudioElement),
        ElementNodeTypeId(HTMLBaseElementTypeId) => generate_element!(HTMLBaseElement),
        ElementNodeTypeId(HTMLBodyElementTypeId) => generate_element!(HTMLBodyElement),
        ElementNodeTypeId(HTMLBRElementTypeId) => generate_element!(HTMLBRElement),
        ElementNodeTypeId(HTMLButtonElementTypeId) => generate_element!(HTMLButtonElement),
        ElementNodeTypeId(HTMLCanvasElementTypeId) => generate_element!(HTMLCanvasElement),
        ElementNodeTypeId(HTMLDataElementTypeId) => generate_element!(HTMLDataElement),
        ElementNodeTypeId(HTMLDataListElementTypeId) => generate_element!(HTMLDataListElement),
        ElementNodeTypeId(HTMLDirectoryElementTypeId) => generate_element!(HTMLDirectoryElement),
        ElementNodeTypeId(HTMLDListElementTypeId) => generate_element!(HTMLDListElement),
        ElementNodeTypeId(HTMLDivElementTypeId) => generate_element!(HTMLDivElement),
        ElementNodeTypeId(HTMLEmbedElementTypeId) => generate_element!(HTMLEmbedElement),
        ElementNodeTypeId(HTMLFieldSetElementTypeId) => generate_element!(HTMLFieldSetElement),
        ElementNodeTypeId(HTMLFontElementTypeId) => generate_element!(HTMLFontElement),
        ElementNodeTypeId(HTMLFormElementTypeId) => generate_element!(HTMLFormElement),
        ElementNodeTypeId(HTMLFrameElementTypeId) => generate_element!(HTMLFrameElement),
        ElementNodeTypeId(HTMLFrameSetElementTypeId) => generate_element!(HTMLFrameSetElement),
        ElementNodeTypeId(HTMLHeadElementTypeId) => generate_element!(HTMLHeadElement),
        ElementNodeTypeId(HTMLHeadingElementTypeId) => generate_element!(HTMLHeadingElement),
        ElementNodeTypeId(HTMLHRElementTypeId) => generate_element!(HTMLHRElement),
        ElementNodeTypeId(HTMLHtmlElementTypeId) => generate_element!(HTMLHtmlElement),
        ElementNodeTypeId(HTMLIframeElementTypeId) => generate_element!(HTMLIFrameElement),
        ElementNodeTypeId(HTMLImageElementTypeId) => generate_element!(HTMLImageElement),
        ElementNodeTypeId(HTMLInputElementTypeId) => generate_element!(HTMLInputElement),
        ElementNodeTypeId(HTMLLabelElementTypeId) => generate_element!(HTMLLabelElement),
        ElementNodeTypeId(HTMLLegendElementTypeId) => generate_element!(HTMLLegendElement),
        ElementNodeTypeId(HTMLLIElementTypeId) => generate_element!(HTMLLIElement),
        ElementNodeTypeId(HTMLLinkElementTypeId) => generate_element!(HTMLLinkElement),
        ElementNodeTypeId(HTMLMapElementTypeId) => generate_element!(HTMLMapElement),
        ElementNodeTypeId(HTMLMediaElementTypeId) => generate_element!(HTMLMediaElement),
        ElementNodeTypeId(HTMLMetaElementTypeId) => generate_element!(HTMLMetaElement),
        ElementNodeTypeId(HTMLMeterElementTypeId) => generate_element!(HTMLMeterElement),
        ElementNodeTypeId(HTMLModElementTypeId) => generate_element!(HTMLModElement),
        ElementNodeTypeId(HTMLObjectElementTypeId) => generate_element!(HTMLObjectElement),
        ElementNodeTypeId(HTMLOListElementTypeId) => generate_element!(HTMLOListElement),
        ElementNodeTypeId(HTMLOptGroupElementTypeId) => generate_element!(HTMLOptGroupElement),
        ElementNodeTypeId(HTMLOptionElementTypeId) => generate_element!(HTMLOptionElement),
        ElementNodeTypeId(HTMLOutputElementTypeId) => generate_element!(HTMLOutputElement),
        ElementNodeTypeId(HTMLParagraphElementTypeId) => generate_element!(HTMLParagraphElement),
        ElementNodeTypeId(HTMLParamElementTypeId) => generate_element!(HTMLParamElement),
        ElementNodeTypeId(HTMLPreElementTypeId) => generate_element!(HTMLPreElement),
        ElementNodeTypeId(HTMLProgressElementTypeId) => generate_element!(HTMLProgressElement),
        ElementNodeTypeId(HTMLQuoteElementTypeId) => generate_element!(HTMLQuoteElement),
        ElementNodeTypeId(HTMLScriptElementTypeId) => generate_element!(HTMLScriptElement),
        ElementNodeTypeId(HTMLSelectElementTypeId) => generate_element!(HTMLSelectElement),
        ElementNodeTypeId(HTMLSourceElementTypeId) => generate_element!(HTMLSourceElement),
        ElementNodeTypeId(HTMLSpanElementTypeId) => generate_element!(HTMLSpanElement),
        ElementNodeTypeId(HTMLStyleElementTypeId) => generate_element!(HTMLStyleElement),
        ElementNodeTypeId(HTMLTableElementTypeId) => generate_element!(HTMLTableElement),
        ElementNodeTypeId(HTMLTableCellElementTypeId) => generate_element!(HTMLTableCellElement),
        ElementNodeTypeId(HTMLTableCaptionElementTypeId) => generate_element!(HTMLTableCaptionElement),
        ElementNodeTypeId(HTMLTableColElementTypeId) => generate_element!(HTMLTableColElement),
        ElementNodeTypeId(HTMLTableRowElementTypeId) => generate_element!(HTMLTableRowElement),
        ElementNodeTypeId(HTMLTableSectionElementTypeId) => generate_element!(HTMLTableSectionElement),
        ElementNodeTypeId(HTMLTemplateElementTypeId) => generate_element!(HTMLTemplateElement),
        ElementNodeTypeId(HTMLTextAreaElementTypeId) => generate_element!(HTMLTextAreaElement),
        ElementNodeTypeId(HTMLTimeElementTypeId) => generate_element!(HTMLTimeElement),
        ElementNodeTypeId(HTMLTitleElementTypeId) => generate_element!(HTMLTitleElement),
        ElementNodeTypeId(HTMLTrackElementTypeId) => generate_element!(HTMLTrackElement),
        ElementNodeTypeId(HTMLUListElementTypeId) => generate_element!(HTMLUListElement),
        ElementNodeTypeId(HTMLVideoElementTypeId) => generate_element!(HTMLVideoElement),
        ElementNodeTypeId(HTMLUnknownElementTypeId) => generate_element!(HTMLUnknownElement),
        CommentNodeTypeId => generate_element!(Comment),
        DoctypeNodeTypeId => generate_element!(DocumentType<ScriptView>),
        TextNodeTypeId => generate_element!(Text)
     }
}

impl Reflectable for AbstractNode<ScriptView> {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        do self.with_base |base| {
            unsafe { cast::transmute(base.reflector()) }
        }
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        do self.with_mut_base |base| {
            unsafe { cast::transmute(base.reflector()) }
        }
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        fail!(~"need to implement wrapping");
    }
}

impl Traceable for Node<ScriptView> {
    fn trace(&self, tracer: *mut JSTracer) {
        #[fixed_stack_segment]
        fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode<ScriptView>>, name: &str) {
            if node.is_none() {
                return;
            }
            debug!("tracing %s", name);
            let node = node.unwrap();
            let obj = node.reflector().get_jsobject();
            assert!(obj.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), obj, JSTRACE_OBJECT as u32);
                }
            }
        }
        debug!("tracing %p?:", self.reflector_.get_jsobject());
        trace_node(tracer, self.parent_node, "parent");
        trace_node(tracer, self.first_child, "first child");
        trace_node(tracer, self.last_child, "last child");
        trace_node(tracer, self.next_sibling, "next sibling");
        trace_node(tracer, self.prev_sibling, "prev sibling");
    }
}