added Info.plist
[TestXSLT.git] / libsablot / src / engine / jsdom.cpp
1 /* 
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  * 
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  * 
12  * The Original Code is the Sablotron XSLT Processor.
13  * 
14  * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15  * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16  * Ginger Alliance Ltd. All Rights Reserved.
17  * 
18  * Contributor(s): Han Qi
19  * 
20  * Alternatively, the contents of this file may be used under the
21  * terms of the GNU General Public License Version 2 or later (the
22  * "GPL"), in which case the provisions of the GPL are applicable 
23  * instead of those above.  If you wish to allow use of your 
24  * version of this file only under the terms of the GPL and not to
25  * allow others to use your version of this file under the MPL,
26  * indicate your decision by deleting the provisions above and
27  * replace them with the notice and other provisions required by
28  * the GPL.  If you do not delete the provisions above, a recipient
29  * may use your version of this file under either the MPL or the
30  * GPL.
31  */
32
33 #include "jsdom.h"
34
35 #ifdef ENABLE_JS
36
37 #define SablotAsExport
38 #include "base.h"
39 #include "sdom.h"
40 #include "verts.h"
41
42 #define declPRIV  NodePrivate *np = (NodePrivate*)JS_GetPrivate(cx, obj)
43 #define NPDOM np->situa->dom()
44
45 /************************ domex  *********************/
46
47 void domexFinalize(JSContext *cx, JSObject *obj)
48 {
49   DomExPrivate *priv = (DomExPrivate*)JS_GetPrivate(cx, obj);
50   if (priv) {
51     delete priv;
52   }
53 }
54
55 JSClass domexClass = {
56   "DOMException",
57   JSCLASS_HAS_PRIVATE,
58   JS_PropertyStub, JS_PropertyStub,
59   JS_PropertyStub,
60   JS_PropertyStub,
61   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
62   domexFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
63 };
64
65 JSBool domexGetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
66 {
67   *vp = id;
68   return TRUE;
69 }
70
71 JS_PROP(domexGetCode)
72 {
73   DomExPrivate *priv = (DomExPrivate*)JS_GetPrivate(cx, obj);
74   *rval = INT_TO_JSVAL(priv -> code);
75   return TRUE;
76 }
77
78 JSPropertySpec domexProtoProps[] =
79 {
80   {"INDEX_SIZE_ERR", 1, PROP_OPT, domexGetProperty, NULL},
81   {"STRING_SIZE_ERR", 2, PROP_OPT, domexGetProperty, NULL},
82   {"HIERARCHY_REQUEST_ERR", 3, PROP_OPT, domexGetProperty, NULL},
83   {"WRONG_DOCUMENT_ERR", 4, PROP_OPT, domexGetProperty, NULL},
84   {"INVALID_CHARACTER_ERR", 5, PROP_OPT, domexGetProperty, NULL},
85   {"NO_DATA_ALLOWED_ERR", 6, PROP_OPT, domexGetProperty, NULL},
86   {"NO_MODIFICATION_ALLOWED_ERR", 7, PROP_OPT, domexGetProperty, NULL},
87   {"NOT_FOUND_ERR", 8, PROP_OPT, domexGetProperty, NULL},
88   {"NOT_SUPPORTED_ERR", 9, PROP_OPT, domexGetProperty, NULL},
89   {"INUSE_ATTRIBUTE_ERR", 10, PROP_OPT, domexGetProperty, NULL},
90   {"INVALID_STATE_ERR", 11, PROP_OPT, domexGetProperty, NULL},
91   {"SYNTAX_ERR", 12, PROP_OPT, domexGetProperty, NULL},
92   {"INVALID_MODIFICATION_ERR", 13, PROP_OPT, domexGetProperty, NULL},
93   {"NAMESPACE_ERR", 14, PROP_OPT, domexGetProperty, NULL},
94   {"INVALID_ACCESS_ERR", 15, PROP_OPT, domexGetProperty, NULL},
95   {NULL, 0, 0, 0, 0}
96 };
97
98 JS_METHOD(domexToString)
99 {
100   DomExPrivate *priv = (DomExPrivate*)JS_GetPrivate(cx, obj);
101   char buff[128];
102   //find the entry
103   JSPropertySpec* aux = domexProtoProps;
104   while (aux -> name)
105     {
106       if (aux -> tinyid == priv -> code) break;
107       aux++;
108     }
109
110   sprintf(buff, "[DOMException %d = %s]", priv -> code,
111           aux -> name ? aux -> name : "unknown code");
112   JSString *str = JS_NewStringCopyZ(cx, buff);
113   *rval = STRING_TO_JSVAL(str);
114   return TRUE;
115 }
116
117 JSPropertySpec domexProps[] =
118 {
119   {"code", 0, PROP_OPT, domexGetCode, NULL},
120   {NULL, 0, 0, 0, 0}
121 };
122
123 JSFunctionSpec domexFunctions[] =
124 {
125   {"toString", domexToString, 0, 0, 0},
126   {NULL, 0, 0, 0, 0}
127 };
128
129 /***************nodelist array **********************/
130
131 JS_METHOD(nlistItem)
132 {
133   JSBool rv;
134   if (argc >= 1) {
135     rv = JS_GetElement(cx, obj, JSVAL_TO_INT(argv[0]), rval);
136   } 
137   else {
138     *rval = JSVAL_VOID;
139     rv = TRUE;
140   }
141   return rv;
142 }
143
144 //  JS_METHOD(nlistDebug)
145 //  {
146 //    JSObject *foo = obj;
147 //    while (foo)
148 //      {
149 //        JSClass *cls = JS_GetClass(foo);
150 //        printf("---> clsname: %s\n", cls -> name);
151 //        foo = JS_GetPrototype(cx, foo);
152 //      }
153
154 //    return TRUE;
155 //  }
156
157 JS_METHOD(nlistAppend)
158 {
159   jsuint len;
160   JS_GetArrayLength(cx, obj, &len);
161   for (unsigned int i = 0; i < argc; i++)
162     {
163       JS_SetElement(cx, obj, len++, &argv[i]);
164     }
165   return TRUE;
166 }
167
168 JS_METHOD(nlistRemove)
169 {
170   if (argc > 0)
171     {
172       JS_DeleteElement(cx, obj, JSVAL_TO_INT(argv[0]));
173     }
174   return TRUE;
175 }
176
177 JSFunctionSpec nlistFunctions[] = {
178   {"item", nlistItem, 0, 0, 0},
179   {"append", nlistAppend, 0, 0, 0},
180   //{"remove", nlistRemove, 0, 0, 0}, //BUGGY
181    {NULL, 0, 0, 0, 0}
182 };
183
184 JS_METHOD(nlistConstructor)
185 {
186   //create an array object to replace obj instance
187   JSObject *arr = JS_NewArrayObject(cx, 0, NULL);
188   
189   //get array prototypr (all methods)
190 //    JSContextItem *cxi = (JSContextItem*)JS_GetContextPrivate(cx);
191 //    assert(cxi);
192 //    if (cxi -> array_proto) 
193 //      {
194 //        //JS_SetPrototype(cx, obj, cxi -> array_proto);
195 //        JS_SetPrototype(cx, arr, cxi -> array_proto);
196 //      }
197
198   //set original object as a prototype of returned array
199   JS_SetPrototype(cx, arr, obj);
200   //set specific object methods
201   JS_DefineFunctions(cx, obj, nlistFunctions);
202
203   *rval = OBJECT_TO_JSVAL(arr);
204   return TRUE;
205 }
206
207 JSClass nlistClass = {
208   "NodeList", 0,
209   JS_PropertyStub,
210   JS_PropertyStub,
211   JS_PropertyStub,
212   JS_PropertyStub,
213   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
214   JS_FinalizeStub,
215   0,
216   0,
217   NULL,
218   nlistConstructor, NULL, NULL, 0, 0
219 };
220
221 /******************** dom implementation ************/
222
223 JSClass domimplClass = {
224   "DOMImplementation", 0,
225   JS_PropertyStub, JS_PropertyStub,
226   JS_PropertyStub,
227   JS_PropertyStub,
228   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
229   JS_FinalizeStub, 0, 0, NULL, NULL, NULL, NULL, 0, 0
230 };
231
232 JS_METHOD(domimplHasFeature)
233 {
234   *rval = JSVAL_FALSE;
235   return TRUE;
236 }
237
238 JS_METHOD(domimplCreateDocumentType)
239 {
240   DOM_EX( 9 );
241   return TRUE;
242 }
243
244 JS_METHOD(domimplCreateDocument)
245 {
246   DOM_EX( 9 );
247   return TRUE;
248 }
249
250 JSFunctionSpec domimplFunctions[] = {
251   {"hasFeature", domimplHasFeature, 0, 0, 0},
252   {"createDocumentType", domimplCreateDocumentType, 0, 0, 0},
253   {"createDocument", domimplCreateDocument, 0, 0, 0},
254   {NULL, 0, 0, 0, 0}
255 };
256
257 /************************ node  *********************/
258 void* _jsdom_getNodePrivate(Sit S, NodeHandle node)
259 {
260   NodePrivate *np = new NodePrivate;
261   np -> situa = &S;
262   np -> node = node;
263   return (void*)np;
264 }
265
266 JSBool nodeGetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
267 {
268   *vp = id;
269   return TRUE;
270 }
271
272 void nodeFinalize(JSContext *cx, JSObject *obj)
273 {
274   NodePrivate *np = (NodePrivate*)JS_GetPrivate(cx, obj);
275   if (np) {
276     delete np;
277   }
278 }
279
280
281 JS_PROP(nodeGetNodeName)
282 {
283   declPRIV;
284   if (np) {
285     char* val;
286     Bool doFree = FALSE;
287     switch(NPDOM.getNodeType(np->node)) {
288     case ELEMENT_NODE:
289     case ATTRIBUTE_NODE:
290     case PROCESSING_INSTRUCTION_NODE:
291       val = (char *)NPDOM.getNodeName(np->node);
292       doFree = TRUE;
293       break;
294     case TEXT_NODE:
295       val = "#text";
296       break;
297     case COMMENT_NODE:
298       val = "#comment";
299       break;
300     case DOCUMENT_NODE:
301       val = "#document";
302       break;
303     default:
304       /* NAMESPACE_NODE - not in DOM 2;
305        * CDATASection, DocumentFragment, DocumentType,
306        * Entity,EntityReference, Notation - not in Sablotron
307        */
308       val = (char *)NPDOM.getNodeName(np->node);
309       doFree = TRUE;
310     }
311     JSString *str = JS_NewStringCopyZ(cx, val);
312     if (doFree) NPDOM.freeName(np->node, val);
313     *rval = STRING_TO_JSVAL(str);
314     return TRUE;
315   } 
316   else {
317     return FALSE;
318   }
319 }
320
321 JS_PROP(nodeGetNodeValue)
322 {
323   declPRIV;
324   if (np) {
325     char* val = (char *)NPDOM.getNodeValue(np->node);
326     JSString *str = JS_NewStringCopyZ(cx, val);
327     NPDOM.freeValue(np->node, val);
328     *rval = STRING_TO_JSVAL(str);
329     return TRUE;
330   } 
331   else {
332     return FALSE;
333   }
334 }
335
336 JS_PROP(nodeGetNodeType)
337 {
338   declPRIV;
339   if (np) {
340     *rval = INT_TO_JSVAL(NPDOM.getNodeType(np->node));
341     return TRUE;
342   } 
343   else {
344     return FALSE;
345   }
346 }
347
348 JS_PROP(nodeGetParentNode)
349 {
350   declPRIV;
351   if (np) {
352     JSObject *o = jsdom_createNode(cx, np, NPDOM.getParent(np->node));
353     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
354     return TRUE;
355   }
356   else {
357     return FALSE;
358   }
359 }
360
361 JS_PROP(nodeGetChildNodes)
362 {
363   declPRIV;
364   if (np) {
365     JSObject *arr = jsdom_createNodeList(cx, 0);
366     *rval = OBJECT_TO_JSVAL(arr);
367     int count = NPDOM.getChildCount(np->node);
368     for (int i = 0; i < count; i++)
369       {
370         JSObject *x = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, i));
371         jsval xx = OBJECT_TO_JSVAL(x);
372         JS_SetElement(cx, arr, i, &xx);
373       }
374     return TRUE;
375   }
376   else {
377     return FALSE;
378   }
379 }
380
381 JS_PROP(nodeGetFirstChild)
382 {
383   declPRIV;
384   if (np) {
385     JSObject *o = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, 0));
386     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
387     return TRUE;
388   }
389   else {
390     return FALSE;
391   }
392 }
393
394 JS_PROP(nodeGetLastChild)
395 {
396   declPRIV;
397   if (np) {
398     JSObject *o = jsdom_createNode(cx, np, 
399                                    NPDOM.getChildNo(np->node, 
400                                                     NPDOM.getChildCount(np->node) - 1 ));
401     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
402     return TRUE;
403   }
404   else {
405     return FALSE;
406   }
407 }
408
409 JS_PROP(nodeGetPreviousSibling)
410 {
411   declPRIV;
412   if (np) {
413     JSObject *o = jsdom_createNode(cx, np, NPDOM.getPreviousSibling(np->node));
414     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
415     return TRUE;
416   }
417   else {
418     return FALSE;
419   }
420 }
421
422 JS_PROP(nodeGetNextSibling)
423 {
424   declPRIV;
425   if (np) {
426     JSObject *o = jsdom_createNode(cx, np, NPDOM.getNextSibling(np->node));
427     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
428     return TRUE;
429   }
430   else {
431     return FALSE;
432   }
433 }
434
435 JS_PROP(nodeGetAttributes)
436 {
437   declPRIV;
438   if (np) {
439     if (NPDOM.getNodeType(np->node) == ELEMENT_NODE) {
440       JSObject *nmap = jsdom_createNamedNodeMap(cx, 0);
441       //iterate attributes
442       int attcount = NPDOM.getAttributeCount(np->node);
443       for (int i = 0; i < attcount; i++)
444         {
445           SXP_Node n = NPDOM.getAttributeNo(np->node, i);
446           JSObject *att = jsdom_wrapNode(*(np->situa), cx, n);
447           jsval val = OBJECT_TO_JSVAL(att);
448           char *name = (char *)NPDOM.getNodeName(n);
449           JS_SetProperty(cx, nmap, name, &val);
450           NPDOM.freeName(n,name);
451         }
452       //return 
453       *rval = OBJECT_TO_JSVAL(nmap);
454     } else {
455       *rval = JSVAL_NULL;
456     }
457     return TRUE;
458   }
459   else {
460     return FALSE;
461   }
462 }
463
464 JS_PROP(nodeGetOwnerDocument)
465 {
466   declPRIV;
467   if (np) {
468     JSObject *o = jsdom_createNode(cx, np, NPDOM.getOwnerDocument(np->node));
469     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
470     return TRUE;
471   }
472   else {
473     return FALSE;
474   }
475 }
476
477 JS_PROP(nodeGetNamespaceUri)
478 {
479   declPRIV;
480   if (np) {
481     char* val = (char *)NPDOM.getNodeNameURI(np->node);
482     if (val) {
483       JSString *str = JS_NewStringCopyZ(cx, val);
484       *rval = STRING_TO_JSVAL(str);
485     } 
486     else {
487       *rval = JSVAL_NULL;
488     }
489     NPDOM.freeName(np->node,val);
490     return TRUE;
491   } 
492   else {
493     return FALSE;
494   }
495 }
496
497 JS_PROP(nodeGetPrefix)
498 {
499   declPRIV;
500   if (np) {
501     char *val = NULL, *colon = NULL;
502     bool doFree = false;
503     switch(NPDOM.getNodeType(np->node)) {
504     case TEXT_NODE:
505     case DOCUMENT_NODE:
506     case COMMENT_NODE:
507       break;
508     case ELEMENT_NODE:
509     case ATTRIBUTE_NODE:
510     case PROCESSING_INSTRUCTION_NODE:
511     default: // see comment within nodeGetNodeName 
512       val = (char *)NPDOM.getNodeName(np->node);
513       colon = strchr(val,':');
514       doFree = true;
515     }
516     if (val && colon) {
517       JSString *str = JS_NewStringCopyN(cx, val, colon - val);
518       *rval = STRING_TO_JSVAL(str);
519     } 
520     else {
521       *rval = JSVAL_NULL;
522     }
523     if (doFree) NPDOM.freeName(np->node, val);
524     return TRUE;
525   } 
526   else {
527     return FALSE;
528   }
529 }
530
531 JS_PROP(nodeGetLocalName)
532 {
533   declPRIV;
534   if (np) {
535     char* val = (char *)NPDOM.getNodeNameLocal(np->node);
536     if (val) {
537       JSString *str = JS_NewStringCopyZ(cx, val);
538       *rval = STRING_TO_JSVAL(str);
539     } 
540     else {
541       *rval = JSVAL_NULL;
542     }
543     NPDOM.freeName(np->node,val);
544     return TRUE;
545   } 
546   else {
547     return FALSE;
548   }
549 }
550
551 JS_METHOD(nodeToString)
552 {
553   declPRIV;
554   if (np) {
555     DStr val;
556     NPDOM.constructStringValue(np->node, val);
557     JSString *str = JS_NewStringCopyZ(cx, (char*)val);
558     *rval = STRING_TO_JSVAL(str);
559     return TRUE;
560   } 
561   else {
562     return FALSE;
563   }
564 }
565
566 JS_METHOD(nodeUnsupported)
567 {
568   DOM_EX( 9 );
569   return TRUE;
570 }
571
572 JS_METHOD(nodeHasChildNodes)
573 {
574   declPRIV;
575   if (np) {
576     if (NPDOM.getChildCount(np->node)) *rval = JSVAL_TRUE;
577     else *rval = JSVAL_FALSE;
578     return TRUE;
579   }
580   else {
581     return FALSE;
582   }
583 }
584
585 JS_METHOD(nodeNormalize)
586 {
587   //simply does nothing
588   return TRUE;
589 }
590
591 JS_METHOD(nodeIsSupported)
592 {
593   //harmlessly unsupported
594   *rval = JSVAL_FALSE;
595   return TRUE;
596 }
597
598 JS_METHOD(nodeHasAttributes)
599 {
600   declPRIV;
601   if (np) {
602     if (NPDOM.getAttributeCount(np->node)) *rval = JSVAL_TRUE;
603     else *rval = JSVAL_FALSE;
604     return TRUE;
605   }
606   else {
607     return FALSE;
608   }
609 }
610
611 JSClass nodeClass = {
612   "Node",
613   JSCLASS_HAS_PRIVATE,
614   JS_PropertyStub, JS_PropertyStub,
615   JS_PropertyStub,
616   JS_PropertyStub,
617   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
618   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
619 };
620
621 //node prototype properties
622 JSPropertySpec nodeProtoProps[] =
623 {
624   //nodetype constants
625   {"ELEMENT_NODE",  SDOM_ELEMENT_NODE, 
626    PROP_OPT, nodeGetProperty, NULL},
627   {"ATTRIBUTE_NODE",  SDOM_ATTRIBUTE_NODE, 
628    PROP_OPT, nodeGetProperty, NULL},
629   {"TEXT_NODE",  SDOM_TEXT_NODE, 
630    PROP_OPT, nodeGetProperty, NULL},
631   {"CDATA_SECTION_NODE",  SDOM_CDATA_SECTION_NODE, 
632    PROP_OPT, nodeGetProperty, NULL},
633   {"ENTITY_REFERENCE_NODE",  SDOM_ENTITY_REFERENCE_NODE, 
634    PROP_OPT, nodeGetProperty, NULL},
635   {"ENTITY_NODE",  SDOM_ENTITY_NODE, 
636    PROP_OPT, nodeGetProperty, NULL},
637   {"PROCESSING_INSTRUCTION_NODE",  SDOM_PROCESSING_INSTRUCTION_NODE, 
638    PROP_OPT, nodeGetProperty, NULL},
639   {"COMMENT_NODE",  SDOM_COMMENT_NODE, 
640    PROP_OPT, nodeGetProperty, NULL},
641   {"DOCUMENT_NODE",  SDOM_DOCUMENT_NODE, 
642    PROP_OPT, nodeGetProperty, NULL},
643   {"DOCUMENT_TYPE_NODE",  SDOM_DOCUMENT_TYPE_NODE, 
644    PROP_OPT, nodeGetProperty, NULL},
645   {"DOCUMENT_FRAGMENT_NODE",  SDOM_DOCUMENT_FRAGMENT_NODE, 
646    PROP_OPT, nodeGetProperty, NULL},
647   {"NOTATION_NODE",  SDOM_NOTATION_NODE , 
648    PROP_OPT, nodeGetProperty, NULL},
649   {NULL, 0, 0, 0, 0}
650 };
651
652 //'real' node props
653 JSPropertySpec nodeProps[] =
654 {
655   //other properties
656   {"nodeName", 0, PROP_OPT, nodeGetNodeName, NULL},
657   {"nodeValue", 0, PROP_OPT, nodeGetNodeValue, NULL},
658   {"nodeType", 0, PROP_OPT, nodeGetNodeType, NULL},
659   {"parentNode", 0, PROP_OPT, nodeGetParentNode, NULL},
660   {"childNodes", 0, PROP_OPT, nodeGetChildNodes, NULL},
661   {"firstChild", 0, PROP_OPT, nodeGetFirstChild, NULL},
662   {"lastChild", 0, PROP_OPT, nodeGetLastChild, NULL},
663   {"previousSibling", 0, PROP_OPT, nodeGetPreviousSibling, NULL},
664   {"nextSibling", 0, PROP_OPT, nodeGetNextSibling, NULL},
665   {"attributes", 0, PROP_OPT, nodeGetAttributes, NULL},
666   {"ownerDocument", 0, PROP_OPT, nodeGetOwnerDocument, NULL},
667   {"namespaceURI", 0, PROP_OPT, nodeGetNamespaceUri, NULL},
668   {"prefix", 0, PROP_OPT, nodeGetPrefix, NULL},
669   {"localName", 0, PROP_OPT, nodeGetLocalName, NULL},
670   {NULL, 0, 0, 0, 0}  
671 };
672
673
674 JSFunctionSpec nodeFunctions[] = 
675 {
676   //unsupported
677   {"toString", nodeToString, 0, 0, 0},
678   {"insertBefore", nodeUnsupported, 0, 0, 0},
679   {"replaceChild", nodeUnsupported, 0, 0, 0},
680   {"removeChild", nodeUnsupported, 0, 0, 0},
681   {"appendChild", nodeUnsupported, 0, 0, 0},
682   {"cloneNode", nodeUnsupported, 0, 0, 0},
683   //supported
684   {"hasChildNodes", nodeHasChildNodes, 0, 0, 0},
685   {"normalize", nodeNormalize, 0, 0, 0},
686   {"isSupported", nodeIsSupported, 0, 0, 0},
687   {"hasAttributes", nodeHasAttributes, 0, 0, 0},
688   {NULL, 0, 0, 0, 0}
689 };
690
691 /************************** document ***********************/
692
693 JSClass documentClass = {
694   "Document",
695   JSCLASS_HAS_PRIVATE,
696   JS_PropertyStub, JS_PropertyStub,
697   JS_PropertyStub,
698   JS_PropertyStub,
699   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
700   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
701 };
702
703 JS_PROP(docGetType)
704 {
705   *rval = JSVAL_VOID;
706   return TRUE;
707 }
708
709 JS_PROP(docGetImplementation)
710 {
711   JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
712   assert(item);
713
714   *rval = OBJECT_TO_JSVAL(item -> domimpl);
715   return TRUE;
716 }
717
718 JS_PROP(docGetDocumentElement)
719 {
720   declPRIV;
721   if (np) {
722     JSObject *o = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, 0));
723     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
724     return TRUE;
725   }
726   else {
727     return FALSE;
728   }
729 }
730
731 JS_METHOD(docElementsByTagName)
732 {
733   DOM_EX( 9 );
734   return TRUE;
735 }
736
737 JS_METHOD(docElementsByTagNameNS)
738 {
739   DOM_EX( 9 );
740   return TRUE;
741 }
742
743 JSPropertySpec documentProps[] = {
744   {"doctype", 0, PROP_OPT, docGetType, NULL},
745   {"implementation", 0, PROP_OPT, docGetImplementation, NULL},
746   {"documentElement", 0, PROP_OPT, docGetDocumentElement, NULL},
747   {NULL, 0, 0, 0, 0}
748 };
749
750 JSFunctionSpec documentFunctions[] = {
751   //not needed
752   {"createElement", nodeUnsupported, 0, 0, 0},
753   {"createDocumentFragment", nodeUnsupported, 0, 0, 0},
754   {"createTextNode", nodeUnsupported, 0, 0, 0},
755   {"createComment", nodeUnsupported, 0, 0, 0},
756   {"createCDATASection", nodeUnsupported, 0, 0, 0},
757   {"createProcessingInstruction", nodeUnsupported, 0, 0, 0},
758   {"createAttribute", nodeUnsupported, 0, 0, 0},
759   {"createEntityReference", nodeUnsupported, 0, 0, 0},
760   {"importNode", nodeUnsupported, 0, 0, 0},
761   {"createElementNS", nodeUnsupported, 0, 0, 0},
762   {"createAttributeNS", nodeUnsupported, 0, 0, 0},
763   //we do not support ids
764   {"getElementsById", nodeUnsupported, 0, 0, 0},
765   //should be supported
766   {"getElementsByTagName", docElementsByTagName, 0, 0, 0},
767   {"getElementsByTagNameNS", docElementsByTagNameNS, 0, 0, 0},
768   {NULL, 0, 0, 0, 0}
769 };
770
771 /************************** element ************************/
772
773 JSClass elementClass = {
774   "Element",
775   JSCLASS_HAS_PRIVATE,
776   JS_PropertyStub, JS_PropertyStub,
777   JS_PropertyStub,
778   JS_PropertyStub,
779   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
780   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
781 };
782
783
784 JS_PROP(eleGetTagName)
785 {
786   declPRIV;
787   if (np) {
788     char *name;
789     name = (char *)NPDOM.getNodeName(np->node);
790     JSString *jname = JS_NewStringCopyZ(cx, name);
791     *rval = STRING_TO_JSVAL(jname);
792     NPDOM.freeName(np->node, name);
793     return TRUE;
794   }
795   else {
796     return FALSE;
797   }
798 }
799
800 JS_METHOD(eleGetAttribute)
801
802   declPRIV;
803   if (argc < 1) 
804     {
805       JS_ReportError(cx, "Element.getAttribute must have one parameter");
806       return FALSE;
807     }
808   if (np) {
809     JSString *str = JSVAL_TO_STRING(argv[0]);
810     char *name = JS_GetStringBytes(str);
811     char *value;
812     int attcount = NPDOM.getAttributeCount(np->node);
813     char *attname;
814     NodeHandle attnode;
815     JSString *jval;
816     for (int i = 0; i < attcount; i++) {
817       attnode = NPDOM.getAttributeNo(np->node, i);
818       attname = (char *)NPDOM.getNodeName(attnode);
819       if ( !strcmp(name, attname) ) {
820         value = (char *)NPDOM.getNodeValue(attnode);
821         jval = JS_NewStringCopyZ(cx, value);
822         *rval = STRING_TO_JSVAL(jval);  
823         NPDOM.freeValue(attnode, value);
824         NPDOM.freeName(attnode, attname);
825         return TRUE;
826       };
827       NPDOM.freeName(attnode, attname);
828     };
829     jval = JS_NewStringCopyZ(cx, "");
830     *rval = STRING_TO_JSVAL(jval);
831     return TRUE;
832   }
833   else {
834     return FALSE;
835   }
836 }
837
838 JS_METHOD(eleGetAttributeNode)
839 {
840   declPRIV;
841   if (argc < 1) 
842     {
843       JS_ReportError(cx, "Element.getAttribute must have one parameter");
844       return FALSE;
845     }
846   if (np) {
847     JSString *str = JSVAL_TO_STRING(argv[0]);
848     char *name = JS_GetStringBytes(str);
849     int attcount = NPDOM.getAttributeCount(np->node);
850     char *attname;
851     NodeHandle attnode;
852     for (int i = 0; i < attcount; i++) {
853       attnode = NPDOM.getAttributeNo(np->node, i);
854       attname = (char *)NPDOM.getNodeName(attnode);
855       if ( !strcmp(name, attname) ) {
856         JSObject *o = jsdom_createNode(cx, np, attnode);
857         *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
858         NPDOM.freeName(attnode, attname);
859         return TRUE;
860       };
861       NPDOM.freeName(attnode, attname);
862     };
863     *rval = JSVAL_NULL;
864     return TRUE;
865   }
866   else {
867     return FALSE;
868   }
869 }
870
871 JS_METHOD(eleGetElementsByTagName)
872 {
873   *rval = JSVAL_NULL;
874   return TRUE;
875 }
876
877 JS_METHOD(eleHasAttribute)
878 {
879   declPRIV;
880   if (np) {
881     JSString *str = JSVAL_TO_STRING(argv[0]);
882     char *name = JS_GetStringBytes(str);
883     int attcount = NPDOM.getAttributeCount(np->node);
884     char *attname;
885     NodeHandle attnode;
886     for (int i = 0; i < attcount; i++) {
887       attnode = NPDOM.getAttributeNo(np->node, i);
888       attname = (char *)NPDOM.getNodeName(attnode);
889       if ( !strcmp(name, attname) ) {
890         NPDOM.freeName(attnode, attname);
891         *rval = JSVAL_TRUE;
892         return TRUE;
893       };
894       NPDOM.freeName(attnode, attname);
895     };
896     *rval = JSVAL_FALSE;
897     return TRUE;
898   }
899   else {
900     return FALSE;
901   }
902 }
903
904 JSPropertySpec elementProps[] =
905 {
906   {"tagName", 0, PROP_OPT, eleGetTagName, NULL},
907   {NULL, 0, 0, 0, 0}
908 };
909
910 JSFunctionSpec elementFunctions[] = 
911 {
912   {"getAttribute", eleGetAttribute, 0, 0, 0},
913   {"setAttribute", nodeUnsupported, 0, 0, 0},
914   {"removeAttribute", nodeUnsupported, 0, 0, 0},
915   {"getAttributeNode", eleGetAttributeNode, 0, 0, 0},
916   {"setAttributeNode", nodeUnsupported, 0, 0, 0},
917   {"removeAttributeNode", nodeUnsupported, 0, 0, 0},
918   {"getElementsByTagName", eleGetElementsByTagName, 0, 0, 0},
919   {"getAttributeNS", nodeUnsupported, 0, 0, 0},
920   {"setAttributeNS", nodeUnsupported, 0, 0, 0},
921   {"removeAttributeNS", nodeUnsupported, 0, 0, 0},
922   {"getAttributeNodeNS", nodeUnsupported, 0, 0, 0},
923   {"setAttributeNodeNS", nodeUnsupported, 0, 0, 0},
924   {"getElementsByTagNameNS", nodeUnsupported, 0, 0, 0},
925   {"hasAttribute", eleHasAttribute, 0, 0, 0},
926   {"hasAttributeNS", nodeUnsupported, 0, 0, 0},
927   {NULL, 0, 0, 0, 0}
928 };
929
930 /********************* Attr ************************/
931
932 JSClass attrClass = {
933   "Attr",
934   JSCLASS_HAS_PRIVATE,
935   JS_PropertyStub, JS_PropertyStub,
936   JS_PropertyStub,
937   JS_PropertyStub,
938   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
939   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
940 };
941
942 JS_PROP(attrGetSpecified)
943 {
944   *rval = JSVAL_TRUE;
945   return TRUE;
946 }
947
948 JS_PROP(attrGetOwnerElement)
949 {
950   declPRIV;
951   if (np) {
952     JSObject *o = jsdom_createNode(cx, np, NPDOM.getParent(np->node));
953     *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
954     return TRUE;
955   }
956   else {
957     return FALSE;
958   }
959 }
960
961 JSPropertySpec attrProps[] = {
962   {"name", 0, PROP_OPT, nodeGetNodeName, NULL},
963   {"value", 0, PROP_OPT, nodeGetNodeValue, NULL},
964   {"specified", 0, PROP_OPT, attrGetSpecified, NULL},
965   {"ownerElement", 0, PROP_OPT, attrGetOwnerElement, NULL},
966   {NULL, 0, 0, 0, 0}
967 };
968
969 /******************* character data & Co. **********/
970
971 JSClass chardataClass = {
972   "CharacterData",
973   JSCLASS_HAS_PRIVATE,
974   JS_PropertyStub, JS_PropertyStub,
975   JS_PropertyStub,
976   JS_PropertyStub,
977   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
978   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
979 };
980
981 JS_PROP(chardataGetData)
982 {
983   declPRIV;
984   if (np) {
985     char *val = (char *)NPDOM.getNodeValue(np->node);
986     if (val) {
987       JSString *jval = JS_NewStringCopyZ(cx, val);
988       *rval = STRING_TO_JSVAL(jval);
989     } else {
990       *rval = JSVAL_NULL;
991     }
992     NPDOM.freeValue(np->node, val);
993     return TRUE;
994   }
995   else {
996     return FALSE;
997   }
998 }
999
1000 int _getDataLen(const char* data)
1001 {
1002   return strlen((char *)data);
1003 }
1004
1005 JS_PROP(chardataGetLength)
1006 {
1007   declPRIV;
1008   if (np) {
1009     const char* val = NPDOM.getNodeValue(np->node);
1010     *rval = INT_TO_JSVAL(_getDataLen(val));
1011     NPDOM.freeValue(np->node, (char*)val);
1012     return TRUE;
1013   }
1014   else {
1015     return FALSE;
1016   }
1017 }
1018
1019 JS_METHOD(chardataSubstringData)
1020 {
1021   declPRIV;
1022   if (argc < 2)
1023     {
1024       JS_ReportError(cx, 
1025                      "CharacterData.substringData must have two parameters");
1026       return FALSE;
1027     }
1028   if (np) {
1029     const char *val = NPDOM.getNodeValue(np->node);
1030     int len = _getDataLen(val);
1031     int off = JSVAL_TO_INT(argv[0]);
1032     int count = JSVAL_TO_INT(argv[1]);
1033     JSString *str;
1034     if (off >= len) 
1035       {
1036         str = JS_NewStringCopyZ(cx, "");
1037       } 
1038     else 
1039       {
1040         if (off + count > len) count = len - off;
1041         str = JS_NewStringCopyN(cx, val + off, count);
1042       }
1043     NPDOM.freeValue(np->node, (char*)val);
1044     *rval = STRING_TO_JSVAL(str);
1045     return TRUE;
1046   }
1047   else {
1048     return FALSE;
1049   }
1050 }
1051
1052 JSPropertySpec chardataProps[] = 
1053 {
1054   {"data", 0, PROP_OPT, chardataGetData, NULL},
1055   {"length", 0, PROP_OPT, chardataGetLength, NULL},
1056   {NULL, 0, 0, 0, 0}
1057 };
1058
1059 JSFunctionSpec chardataFunctions[] = 
1060 {
1061   {"substringData", chardataSubstringData, 0, 0, 0},
1062   {"appendData", nodeUnsupported, 0, 0, 0},
1063   {"insertData", nodeUnsupported, 0, 0, 0},
1064   {"deleteData", nodeUnsupported, 0, 0, 0},
1065   {"replaceData", nodeUnsupported, 0, 0, 0},
1066   {NULL, 0, 0, 0, 0}
1067 };
1068
1069 /********************* text ************************/
1070
1071 JSClass textClass = {
1072   "Text",
1073   JSCLASS_HAS_PRIVATE,
1074   JS_PropertyStub, JS_PropertyStub,
1075   JS_PropertyStub,
1076   JS_PropertyStub,
1077   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1078   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1079 };
1080
1081 JSFunctionSpec textFunctions[] = 
1082 {
1083   {"splitText", nodeUnsupported, 0, 0, 0},
1084   {NULL, 0, 0, 0, 0}
1085 };
1086
1087 /******************** cdata ************************/
1088
1089 JSClass cdataClass = {
1090   "CDATASection",
1091   JSCLASS_HAS_PRIVATE,
1092   JS_PropertyStub, JS_PropertyStub,
1093   JS_PropertyStub,
1094   JS_PropertyStub,
1095   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1096   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1097 };
1098
1099 /***************** comment *************************/
1100
1101 JSClass commentClass = {
1102   "Comment",
1103   JSCLASS_HAS_PRIVATE,
1104   JS_PropertyStub, JS_PropertyStub,
1105   JS_PropertyStub,
1106   JS_PropertyStub,
1107   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1108   nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1109 };
1110
1111 /********************* named node map **************/
1112
1113 JS_PROP(nnmGetLength)
1114 {
1115   JSIdArray *arr = JS_Enumerate(cx, obj);
1116   *rval = INT_TO_JSVAL(arr -> length - 1);
1117   JS_DestroyIdArray(cx, arr);
1118   return TRUE;
1119 }
1120
1121 JS_METHOD(nnmGetNamedItem)
1122 {
1123   JSBool rv;
1124   if (argc != 1) 
1125     {
1126       JS_ReportError(cx, "NamedNodeMap.getNamedItem must have one parameter");
1127       return FALSE;
1128     }
1129   JSString *str = JSVAL_TO_STRING(argv[0]);
1130   jsval value;
1131   char *name = JS_GetStringBytes(str);
1132   rv = JS_GetProperty(cx, obj, name, &value);
1133   if (rv) *rval = value;
1134   return rv;
1135 }
1136
1137 JS_METHOD(nnmSetNamedItem)
1138 {
1139   if (argc != 1) 
1140     {
1141       JS_ReportError(cx, "NamedNodeMap.setNamedItem must have one parameter");
1142       return FALSE;
1143     }
1144   //check the type here!!!
1145   JSObject *nobj = JSVAL_TO_OBJECT(argv[0]);
1146   JSClass *cls = JS_GET_CLASS(cx, nobj);
1147   JSObject *proto = JS_GetPrototype(cx, nobj);
1148   JSContextItem *cxi = (JSContextItem*)JS_GetContextPrivate(cx);
1149   if (proto == cxi->node || cls == &nodeClass)
1150     {
1151       NodePrivate *np = (NodePrivate*)JS_GetPrivate(cx, nobj);
1152       char *name = (char *)NPDOM.getNodeName(np->node);
1153       JS_SetProperty(cx, obj, name, &(argv[0]));
1154       NPDOM.freeName(np->node,name);
1155       return TRUE;
1156     }
1157   else
1158     {
1159       JS_ReportError(cx, "invalid NamedNodeMap.setNamedItem parameter");
1160       return FALSE;
1161     }
1162 }
1163
1164 JS_METHOD(nnmRemoveNamedItem)
1165 {
1166   if (argc != 1) 
1167     {
1168       JS_ReportError(cx, "NamedNodeMap.removeNamedItem must have one parameter");
1169       return FALSE;
1170     }
1171   JSString *str = JSVAL_TO_STRING(argv[0]);
1172   char *name = JS_GetStringBytes(str);
1173   return JS_DeleteProperty(cx, obj, name);
1174 }
1175
1176 JS_METHOD(nnmItem)
1177 {
1178   if (argc >= 1 || ! JSVAL_IS_INT(argv[0]) )
1179     {
1180       JSIdArray *arr = JS_Enumerate(cx, obj);
1181       int idx = JSVAL_TO_INT(argv[0]);
1182       if (idx < 0 || idx >= arr -> length - 1)
1183         {
1184           *rval = JSVAL_VOID;
1185         }
1186       else
1187         {
1188           jsval val;
1189           //skip the 'length' property
1190           JS_IdToValue(cx, arr->vector[idx + 1], &val);
1191           JS_GetProperty(cx, obj, 
1192                          JS_GetStringBytes(JSVAL_TO_STRING(val)), rval);
1193         }
1194       JS_DestroyIdArray(cx, arr);
1195       return TRUE;
1196     }
1197   else
1198     {
1199       JS_ReportError(cx, "NamedNodeMap.item must have one parameter");
1200       return FALSE;
1201     }
1202 }
1203
1204 JSPropertySpec nnmProps[] = {
1205   {"length", 0, PROP_OPT, nnmGetLength, NULL},
1206   {NULL, 0, 0, 0, 0}
1207 };
1208
1209 JSFunctionSpec nnmFunctions[] = {
1210   {"getNamedItem", nnmGetNamedItem, 0, 0, 0},
1211   {"setNamedItem", nnmSetNamedItem, 0, 0, 0},
1212   {"removeNamedItem", nnmRemoveNamedItem, 0, 0, 0},
1213   {"item", nnmItem, 0, 0, 0},
1214   {"getNamedItemsNS", nodeUnsupported, 0, 0, 0},
1215   {"setNamedItemsNS", nodeUnsupported, 0, 0, 0},
1216   {"removeNamedItemsNS", nodeUnsupported, 0, 0, 0},
1217   {NULL, 0, 0, 0, 0}
1218 };
1219
1220 JSClass nnmClass = {
1221   "NamedNodeMap", 0,
1222   JS_PropertyStub,
1223   JS_PropertyStub,
1224   JS_PropertyStub,
1225   JS_PropertyStub,
1226   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1227   JS_FinalizeStub, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1228 };
1229
1230 /********************* functions *******************/
1231
1232 JSClass* _jsdom_getNodeClass(SDOM_NodeType type) 
1233 {
1234   JSClass *cls;
1235   switch (type) 
1236     {
1237     case SDOM_ELEMENT_NODE:
1238       cls = &elementClass;
1239       break;
1240     case SDOM_DOCUMENT_NODE:
1241       cls = &documentClass;
1242       break;
1243     case SDOM_ATTRIBUTE_NODE:
1244       cls = &attrClass;
1245       break;
1246     case SDOM_TEXT_NODE:
1247       cls = &textClass;
1248       break;
1249     case SDOM_CDATA_SECTION_NODE:
1250       cls = &cdataClass;
1251       break;
1252     case SDOM_COMMENT_NODE:
1253       cls = &commentClass;
1254       break;
1255     default:
1256       {
1257         cls = &nodeClass;
1258       }
1259     }
1260   return cls;
1261 }
1262
1263 JSClass* _jsdom_getNodeClass(Sit S, JSContext *cx, NodeHandle node) 
1264 {
1265   return _jsdom_getNodeClass((SDOM_NodeType)S.dom().getNodeType(node));
1266 }
1267
1268 JSObject* jsdom_wrapNode(Sit S, JSContext *cx, NodeHandle node) 
1269 {
1270   JSObject *obj = NULL;
1271   if (node)
1272     {
1273       JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1274       assert(item);
1275       
1276       SDOM_NodeType type = (SDOM_NodeType)S.dom().getNodeType(node);
1277
1278       obj = JS_NewObject(cx, _jsdom_getNodeClass(type), 
1279                                    item->node, NULL);
1280       JS_SetPrivate(cx, obj, _jsdom_getNodePrivate(S, node));
1281
1282       //common methods and properties
1283       JS_DefineProperties(cx, obj, nodeProps);
1284       JS_DefineFunctions(cx, obj, nodeFunctions);
1285       
1286       //tweak the class
1287       switch (type) 
1288         {
1289         case SDOM_ELEMENT_NODE:
1290           {
1291             JS_DefineProperties(cx, obj, elementProps);
1292             JS_DefineFunctions(cx, obj, elementFunctions);
1293           }; break;
1294         case SDOM_DOCUMENT_NODE:
1295           {
1296             JS_DefineProperties(cx, obj, documentProps);
1297             JS_DefineFunctions(cx, obj, documentFunctions);
1298           }; break;
1299         case SDOM_ATTRIBUTE_NODE:
1300           {
1301             JS_DefineProperties(cx, obj, attrProps);
1302           }; break;
1303         case SDOM_TEXT_NODE:
1304           {
1305             JS_DefineProperties(cx, obj, chardataProps);
1306             JS_DefineFunctions(cx, obj, chardataFunctions);
1307             //text specs.
1308             JS_DefineFunctions(cx, obj, textFunctions);
1309           }; break;
1310         case SDOM_CDATA_SECTION_NODE:
1311           {
1312             JS_DefineProperties(cx, obj, chardataProps);
1313             JS_DefineFunctions(cx, obj, chardataFunctions);
1314           }; break;
1315         case SDOM_COMMENT_NODE:
1316           {
1317             JS_DefineProperties(cx, obj, chardataProps);
1318             JS_DefineFunctions(cx, obj, chardataFunctions);
1319           }; break;
1320         }
1321     }
1322   return obj;
1323 }
1324
1325 JSObject* jsdom_createNode(JSContext *cx, NodePrivate *np_, NodeHandle node) 
1326 {
1327   return jsdom_wrapNode(*(np_->situa), cx, node);
1328 }
1329
1330
1331 void jsdom_delegateDOM(JSContext *cx)
1332 {
1333   JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1334   JSObject *obj;
1335   //Node prototype
1336   obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "Node",
1337                         &nodeClass, NULL, 
1338                         JSPROP_ENUMERATE | 
1339                         JSPROP_READONLY |
1340                         JSPROP_PERMANENT);
1341   JS_DefineProperties(cx, obj, nodeProtoProps);
1342   item -> node = obj;
1343   //DOMException prototype
1344   obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "DOMException",
1345                         &domexClass, NULL, 
1346                         JSPROP_ENUMERATE | 
1347                         JSPROP_READONLY |
1348                         JSPROP_PERMANENT);
1349   JS_DefineProperties(cx, obj, domexProtoProps);
1350   item -> domex = obj;
1351   //DOMImplementation
1352   obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "DOMImplementation",
1353                         &domexClass, NULL, 
1354                         JSPROP_ENUMERATE | 
1355                         JSPROP_READONLY |
1356                         JSPROP_PERMANENT);
1357   JS_DefineFunctions(cx, obj, domimplFunctions);
1358   item -> domimpl = obj;
1359   //nodelist class
1360   JSObject *nlclass = JS_InitClass(cx, JS_GetGlobalObject(cx),
1361                                    NULL,
1362                                    &nlistClass, nlistConstructor, 0,
1363                                    NULL, NULL, NULL, NULL);
1364   item -> nlclass = nlclass;
1365   //nodelist class
1366   //  JSObject *nnmclass = JS_InitClass(cx, JS_GetGlobalObject(cx),
1367 //                                  NULL,
1368 //                                  &nnmClass, NULL, 0,
1369 //                                  NULL, nnmFunctions, NULL, NULL);
1370 //    item -> nnmclass = nnmclass;
1371 }
1372
1373 void jsdom_raiseException(JSContext *cx, int code) 
1374 {
1375   JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1376   assert(item);
1377
1378   JSObject *obj = JS_NewObject(cx, &domexClass, item -> domex, NULL);
1379   //set private
1380   DomExPrivate *c = new DomExPrivate;
1381   c -> code = code;
1382   JS_SetPrivate(cx, obj, c);
1383   //instance props. and funcs.
1384   JS_DefineProperties(cx, obj, domexProps);
1385   JS_DefineFunctions(cx, obj, domexFunctions);
1386   //raise exception
1387   JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
1388 }
1389
1390 JSObject* jsdom_createNodeList(JSContext *cx, int num)
1391 {
1392   //JSObject *obj = JS_NewArrayObject(cx, 0, NULL);
1393   //JS_DefineFunctions(cx, obj, nlistFunctions);
1394   JSObject *obj = JS_ConstructObject(cx, &nlistClass, NULL, NULL);
1395
1396   return obj;
1397 }
1398
1399 JSObject* jsdom_createNamedNodeMap(JSContext *cx, int num)
1400 {
1401   JSObject *obj = JS_NewObject(cx, &nnmClass, NULL, NULL);
1402   JS_DefineFunctions(cx, obj, nnmFunctions);
1403   JS_DefineProperties(cx, obj, nnmProps);
1404
1405   return obj;
1406 }
1407
1408 #endif //ENABLE_JS