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
domexFinalize(JSContext * cx,JSObject * obj)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
domexGetProperty(JSContext * cx,JSObject * obj,jsval id,jsval * vp)65 JSBool domexGetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
66 {
67 *vp = id;
68 return TRUE;
69 }
70
JS_PROP(domexGetCode)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
JS_METHOD(domexToString)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
JS_METHOD(nlistItem)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
JS_METHOD(nlistAppend)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
JS_METHOD(nlistRemove)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
JS_METHOD(nlistConstructor)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 // sabassert(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
JS_METHOD(domimplHasFeature)232 JS_METHOD(domimplHasFeature)
233 {
234 *rval = JSVAL_FALSE;
235 return TRUE;
236 }
237
JS_METHOD(domimplCreateDocumentType)238 JS_METHOD(domimplCreateDocumentType)
239 {
240 DOM_EX( 9 );
241 return TRUE;
242 }
243
JS_METHOD(domimplCreateDocument)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 *********************/
_jsdom_getNodePrivate(Sit S,NodeHandle 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
nodeGetProperty(JSContext * cx,JSObject * obj,jsval id,jsval * vp)266 JSBool nodeGetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
267 {
268 *vp = id;
269 return TRUE;
270 }
271
nodeFinalize(JSContext * cx,JSObject * obj)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
JS_PROP(nodeGetNodeName)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
JS_PROP(nodeGetNodeValue)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
JS_PROP(nodeGetNodeType)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
JS_PROP(nodeGetParentNode)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
JS_PROP(nodeGetChildNodes)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
369 for (int i = 0; i < count; i++)
370 {
371 JSObject *x = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, i));
372 jsval xx = OBJECT_TO_JSVAL(x);
373 JS_SetElement(cx, arr, i, &xx);
374 }
375 return TRUE;
376 }
377 else {
378 return FALSE;
379 }
380 }
381
JS_PROP(nodeGetFirstChild)382 JS_PROP(nodeGetFirstChild)
383 {
384 declPRIV;
385 if (np) {
386 JSObject *o = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, 0));
387 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
388 return TRUE;
389 }
390 else {
391 return FALSE;
392 }
393 }
394
JS_PROP(nodeGetLastChild)395 JS_PROP(nodeGetLastChild)
396 {
397 declPRIV;
398 if (np) {
399 JSObject *o = jsdom_createNode(cx, np,
400 NPDOM.getChildNo(np->node,
401 NPDOM.getChildCount(np->node) - 1 ));
402 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
403 return TRUE;
404 }
405 else {
406 return FALSE;
407 }
408 }
409
JS_PROP(nodeGetPreviousSibling)410 JS_PROP(nodeGetPreviousSibling)
411 {
412 declPRIV;
413 if (np) {
414 JSObject *o = jsdom_createNode(cx, np, NPDOM.getPreviousSibling(np->node));
415 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
416 return TRUE;
417 }
418 else {
419 return FALSE;
420 }
421 }
422
JS_PROP(nodeGetNextSibling)423 JS_PROP(nodeGetNextSibling)
424 {
425 declPRIV;
426 if (np) {
427 JSObject *o = jsdom_createNode(cx, np, NPDOM.getNextSibling(np->node));
428 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
429 return TRUE;
430 }
431 else {
432 return FALSE;
433 }
434 }
435
JS_PROP(nodeGetAttributes)436 JS_PROP(nodeGetAttributes)
437 {
438 declPRIV;
439 if (np) {
440 if (NPDOM.getNodeType(np->node) == ELEMENT_NODE) {
441 JSObject *nmap = jsdom_createNamedNodeMap(cx, 0);
442 //iterate attributes
443 int attcount = NPDOM.getAttributeCount(np->node);
444 for (int i = 0; i < attcount; i++)
445 {
446 SXP_Node n = NPDOM.getAttributeNo(np->node, i);
447 JSObject *att = jsdom_wrapNode(*(np->situa), cx, n);
448 jsval val = OBJECT_TO_JSVAL(att);
449 char *name = (char *)NPDOM.getNodeName(n);
450 JS_SetProperty(cx, nmap, name, &val);
451 NPDOM.freeName(n,name);
452 }
453 //return
454 *rval = OBJECT_TO_JSVAL(nmap);
455 } else {
456 *rval = JSVAL_NULL;
457 }
458 return TRUE;
459 }
460 else {
461 return FALSE;
462 }
463 }
464
JS_PROP(nodeGetOwnerDocument)465 JS_PROP(nodeGetOwnerDocument)
466 {
467 declPRIV;
468 if (np) {
469 JSObject *o = jsdom_createNode(cx, np, NPDOM.getOwnerDocument(np->node));
470 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
471 return TRUE;
472 }
473 else {
474 return FALSE;
475 }
476 }
477
JS_PROP(nodeGetNamespaceUri)478 JS_PROP(nodeGetNamespaceUri)
479 {
480 declPRIV;
481 if (np) {
482 char* val = (char *)NPDOM.getNodeNameURI(np->node);
483 if (val) {
484 JSString *str = JS_NewStringCopyZ(cx, val);
485 *rval = STRING_TO_JSVAL(str);
486 }
487 else {
488 *rval = JSVAL_NULL;
489 }
490 NPDOM.freeName(np->node,val);
491 return TRUE;
492 }
493 else {
494 return FALSE;
495 }
496 }
497
JS_PROP(nodeGetPrefix)498 JS_PROP(nodeGetPrefix)
499 {
500 declPRIV;
501 if (np) {
502 char *val = NULL, *colon = NULL;
503 bool doFree = false;
504 switch(NPDOM.getNodeType(np->node)) {
505 case TEXT_NODE:
506 case DOCUMENT_NODE:
507 case COMMENT_NODE:
508 break;
509 case ELEMENT_NODE:
510 case ATTRIBUTE_NODE:
511 case PROCESSING_INSTRUCTION_NODE:
512 default: // see comment within nodeGetNodeName
513 val = (char *)NPDOM.getNodeName(np->node);
514 colon = strchr(val,':');
515 doFree = true;
516 }
517 if (val && colon) {
518 JSString *str = JS_NewStringCopyN(cx, val, colon - val);
519 *rval = STRING_TO_JSVAL(str);
520 }
521 else {
522 *rval = JSVAL_NULL;
523 }
524 if (doFree) NPDOM.freeName(np->node, val);
525 return TRUE;
526 }
527 else {
528 return FALSE;
529 }
530 }
531
JS_PROP(nodeGetLocalName)532 JS_PROP(nodeGetLocalName)
533 {
534 declPRIV;
535 if (np) {
536 char* val = (char *)NPDOM.getNodeNameLocal(np->node);
537 if (val) {
538 JSString *str = JS_NewStringCopyZ(cx, val);
539 *rval = STRING_TO_JSVAL(str);
540 }
541 else {
542 *rval = JSVAL_NULL;
543 }
544 NPDOM.freeName(np->node,val);
545 return TRUE;
546 }
547 else {
548 return FALSE;
549 }
550 }
551
JS_METHOD(nodeToString)552 JS_METHOD(nodeToString)
553 {
554 declPRIV;
555 if (np) {
556 DStr val;
557 NPDOM.constructStringValue(np->node, val);
558 JSString *str = JS_NewStringCopyZ(cx, (char*)val);
559 *rval = STRING_TO_JSVAL(str);
560 return TRUE;
561 }
562 else {
563 return FALSE;
564 }
565 }
566
JS_METHOD(nodeUnsupported)567 JS_METHOD(nodeUnsupported)
568 {
569 DOM_EX( 9 );
570 return TRUE;
571 }
572
JS_METHOD(nodeHasChildNodes)573 JS_METHOD(nodeHasChildNodes)
574 {
575 declPRIV;
576 if (np) {
577 if (NPDOM.getChildCount(np->node)) *rval = JSVAL_TRUE;
578 else *rval = JSVAL_FALSE;
579 return TRUE;
580 }
581 else {
582 return FALSE;
583 }
584 }
585
JS_METHOD(nodeNormalize)586 JS_METHOD(nodeNormalize)
587 {
588 //simply does nothing
589 return TRUE;
590 }
591
JS_METHOD(nodeIsSupported)592 JS_METHOD(nodeIsSupported)
593 {
594 //harmlessly unsupported
595 *rval = JSVAL_FALSE;
596 return TRUE;
597 }
598
JS_METHOD(nodeHasAttributes)599 JS_METHOD(nodeHasAttributes)
600 {
601 declPRIV;
602 if (np) {
603 if (NPDOM.getAttributeCount(np->node)) *rval = JSVAL_TRUE;
604 else *rval = JSVAL_FALSE;
605 return TRUE;
606 }
607 else {
608 return FALSE;
609 }
610 }
611
612 JSClass nodeClass = {
613 "Node",
614 JSCLASS_HAS_PRIVATE,
615 JS_PropertyStub, JS_PropertyStub,
616 JS_PropertyStub,
617 JS_PropertyStub,
618 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
619 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
620 };
621
622 //node prototype properties
623 JSPropertySpec nodeProtoProps[] =
624 {
625 //nodetype constants
626 {"ELEMENT_NODE", SDOM_ELEMENT_NODE,
627 PROP_OPT, nodeGetProperty, NULL},
628 {"ATTRIBUTE_NODE", SDOM_ATTRIBUTE_NODE,
629 PROP_OPT, nodeGetProperty, NULL},
630 {"TEXT_NODE", SDOM_TEXT_NODE,
631 PROP_OPT, nodeGetProperty, NULL},
632 {"CDATA_SECTION_NODE", SDOM_CDATA_SECTION_NODE,
633 PROP_OPT, nodeGetProperty, NULL},
634 {"ENTITY_REFERENCE_NODE", SDOM_ENTITY_REFERENCE_NODE,
635 PROP_OPT, nodeGetProperty, NULL},
636 {"ENTITY_NODE", SDOM_ENTITY_NODE,
637 PROP_OPT, nodeGetProperty, NULL},
638 {"PROCESSING_INSTRUCTION_NODE", SDOM_PROCESSING_INSTRUCTION_NODE,
639 PROP_OPT, nodeGetProperty, NULL},
640 {"COMMENT_NODE", SDOM_COMMENT_NODE,
641 PROP_OPT, nodeGetProperty, NULL},
642 {"DOCUMENT_NODE", SDOM_DOCUMENT_NODE,
643 PROP_OPT, nodeGetProperty, NULL},
644 {"DOCUMENT_TYPE_NODE", SDOM_DOCUMENT_TYPE_NODE,
645 PROP_OPT, nodeGetProperty, NULL},
646 {"DOCUMENT_FRAGMENT_NODE", SDOM_DOCUMENT_FRAGMENT_NODE,
647 PROP_OPT, nodeGetProperty, NULL},
648 {"NOTATION_NODE", SDOM_NOTATION_NODE ,
649 PROP_OPT, nodeGetProperty, NULL},
650 {NULL, 0, 0, 0, 0}
651 };
652
653 //'real' node props
654 JSPropertySpec nodeProps[] =
655 {
656 //other properties
657 {"nodeName", 0, PROP_OPT, nodeGetNodeName, NULL},
658 {"nodeValue", 0, PROP_OPT, nodeGetNodeValue, NULL},
659 {"nodeType", 0, PROP_OPT, nodeGetNodeType, NULL},
660 {"parentNode", 0, PROP_OPT, nodeGetParentNode, NULL},
661 {"childNodes", 0, PROP_OPT, nodeGetChildNodes, NULL},
662 {"firstChild", 0, PROP_OPT, nodeGetFirstChild, NULL},
663 {"lastChild", 0, PROP_OPT, nodeGetLastChild, NULL},
664 {"previousSibling", 0, PROP_OPT, nodeGetPreviousSibling, NULL},
665 {"nextSibling", 0, PROP_OPT, nodeGetNextSibling, NULL},
666 {"attributes", 0, PROP_OPT, nodeGetAttributes, NULL},
667 {"ownerDocument", 0, PROP_OPT, nodeGetOwnerDocument, NULL},
668 {"namespaceURI", 0, PROP_OPT, nodeGetNamespaceUri, NULL},
669 {"prefix", 0, PROP_OPT, nodeGetPrefix, NULL},
670 {"localName", 0, PROP_OPT, nodeGetLocalName, NULL},
671 {NULL, 0, 0, 0, 0}
672 };
673
674
675 JSFunctionSpec nodeFunctions[] =
676 {
677 //unsupported
678 {"toString", nodeToString, 0, 0, 0},
679 {"insertBefore", nodeUnsupported, 0, 0, 0},
680 {"replaceChild", nodeUnsupported, 0, 0, 0},
681 {"removeChild", nodeUnsupported, 0, 0, 0},
682 {"appendChild", nodeUnsupported, 0, 0, 0},
683 {"cloneNode", nodeUnsupported, 0, 0, 0},
684 //supported
685 {"hasChildNodes", nodeHasChildNodes, 0, 0, 0},
686 {"normalize", nodeNormalize, 0, 0, 0},
687 {"isSupported", nodeIsSupported, 0, 0, 0},
688 {"hasAttributes", nodeHasAttributes, 0, 0, 0},
689 {NULL, 0, 0, 0, 0}
690 };
691
692 /************************** document ***********************/
693
694 JSClass documentClass = {
695 "Document",
696 JSCLASS_HAS_PRIVATE,
697 JS_PropertyStub, JS_PropertyStub,
698 JS_PropertyStub,
699 JS_PropertyStub,
700 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
701 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
702 };
703
JS_PROP(docGetType)704 JS_PROP(docGetType)
705 {
706 *rval = JSVAL_VOID;
707 return TRUE;
708 }
709
JS_PROP(docGetImplementation)710 JS_PROP(docGetImplementation)
711 {
712 JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
713 sabassert(item);
714
715 *rval = OBJECT_TO_JSVAL(item -> domimpl);
716 return TRUE;
717 }
718
JS_PROP(docGetDocumentElement)719 JS_PROP(docGetDocumentElement)
720 {
721 declPRIV;
722 if (np) {
723 JSObject *o = jsdom_createNode(cx, np, NPDOM.getChildNo(np->node, 0));
724 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
725 return TRUE;
726 }
727 else {
728 return FALSE;
729 }
730 }
731
JS_METHOD(docElementsByTagName)732 JS_METHOD(docElementsByTagName)
733 {
734 DOM_EX( 9 );
735 return TRUE;
736 }
737
JS_METHOD(docElementsByTagNameNS)738 JS_METHOD(docElementsByTagNameNS)
739 {
740 DOM_EX( 9 );
741 return TRUE;
742 }
743
744 JSPropertySpec documentProps[] = {
745 {"doctype", 0, PROP_OPT, docGetType, NULL},
746 {"implementation", 0, PROP_OPT, docGetImplementation, NULL},
747 {"documentElement", 0, PROP_OPT, docGetDocumentElement, NULL},
748 {NULL, 0, 0, 0, 0}
749 };
750
751 JSFunctionSpec documentFunctions[] = {
752 //not needed
753 {"createElement", nodeUnsupported, 0, 0, 0},
754 {"createDocumentFragment", nodeUnsupported, 0, 0, 0},
755 {"createTextNode", nodeUnsupported, 0, 0, 0},
756 {"createComment", nodeUnsupported, 0, 0, 0},
757 {"createCDATASection", nodeUnsupported, 0, 0, 0},
758 {"createProcessingInstruction", nodeUnsupported, 0, 0, 0},
759 {"createAttribute", nodeUnsupported, 0, 0, 0},
760 {"createEntityReference", nodeUnsupported, 0, 0, 0},
761 {"importNode", nodeUnsupported, 0, 0, 0},
762 {"createElementNS", nodeUnsupported, 0, 0, 0},
763 {"createAttributeNS", nodeUnsupported, 0, 0, 0},
764 //we do not support ids
765 {"getElementsById", nodeUnsupported, 0, 0, 0},
766 //should be supported
767 {"getElementsByTagName", docElementsByTagName, 0, 0, 0},
768 {"getElementsByTagNameNS", docElementsByTagNameNS, 0, 0, 0},
769 {NULL, 0, 0, 0, 0}
770 };
771
772 /************************** element ************************/
773
774 JSClass elementClass = {
775 "Element",
776 JSCLASS_HAS_PRIVATE,
777 JS_PropertyStub, JS_PropertyStub,
778 JS_PropertyStub,
779 JS_PropertyStub,
780 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
781 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
782 };
783
784
JS_PROP(eleGetTagName)785 JS_PROP(eleGetTagName)
786 {
787 declPRIV;
788 if (np) {
789 char *name;
790 name = (char *)NPDOM.getNodeName(np->node);
791 JSString *jname = JS_NewStringCopyZ(cx, name);
792 *rval = STRING_TO_JSVAL(jname);
793 NPDOM.freeName(np->node, name);
794 return TRUE;
795 }
796 else {
797 return FALSE;
798 }
799 }
800
JS_METHOD(eleGetAttribute)801 JS_METHOD(eleGetAttribute)
802 {
803 declPRIV;
804 if (argc < 1)
805 {
806 JS_ReportError(cx, "Element.getAttribute must have one parameter");
807 return FALSE;
808 }
809 if (np) {
810 JSString *str = JSVAL_TO_STRING(argv[0]);
811 char *name = JS_GetStringBytes(str);
812 char *value;
813 int attcount = NPDOM.getAttributeCount(np->node);
814 char *attname;
815 NodeHandle attnode;
816 JSString *jval;
817 for (int i = 0; i < attcount; i++) {
818 attnode = NPDOM.getAttributeNo(np->node, i);
819 attname = (char *)NPDOM.getNodeName(attnode);
820 if ( !strcmp(name, attname) ) {
821 value = (char *)NPDOM.getNodeValue(attnode);
822 jval = JS_NewStringCopyZ(cx, value);
823 *rval = STRING_TO_JSVAL(jval);
824 NPDOM.freeValue(attnode, value);
825 NPDOM.freeName(attnode, attname);
826 return TRUE;
827 };
828 NPDOM.freeName(attnode, attname);
829 };
830 jval = JS_NewStringCopyZ(cx, "");
831 *rval = STRING_TO_JSVAL(jval);
832 return TRUE;
833 }
834 else {
835 return FALSE;
836 }
837 }
838
JS_METHOD(eleGetAttributeNode)839 JS_METHOD(eleGetAttributeNode)
840 {
841 declPRIV;
842 if (argc < 1)
843 {
844 JS_ReportError(cx, "Element.getAttribute must have one parameter");
845 return FALSE;
846 }
847 if (np) {
848 JSString *str = JSVAL_TO_STRING(argv[0]);
849 char *name = JS_GetStringBytes(str);
850 int attcount = NPDOM.getAttributeCount(np->node);
851 char *attname;
852 NodeHandle attnode;
853 for (int i = 0; i < attcount; i++) {
854 attnode = NPDOM.getAttributeNo(np->node, i);
855 attname = (char *)NPDOM.getNodeName(attnode);
856 if ( !strcmp(name, attname) ) {
857 JSObject *o = jsdom_createNode(cx, np, attnode);
858 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
859 NPDOM.freeName(attnode, attname);
860 return TRUE;
861 };
862 NPDOM.freeName(attnode, attname);
863 };
864 *rval = JSVAL_NULL;
865 return TRUE;
866 }
867 else {
868 return FALSE;
869 }
870 }
871
JS_METHOD(eleGetElementsByTagName)872 JS_METHOD(eleGetElementsByTagName)
873 {
874 *rval = JSVAL_NULL;
875 return TRUE;
876 }
877
JS_METHOD(eleHasAttribute)878 JS_METHOD(eleHasAttribute)
879 {
880 declPRIV;
881 if (np) {
882 JSString *str = JSVAL_TO_STRING(argv[0]);
883 char *name = JS_GetStringBytes(str);
884 int attcount = NPDOM.getAttributeCount(np->node);
885 char *attname;
886 NodeHandle attnode;
887 for (int i = 0; i < attcount; i++) {
888 attnode = NPDOM.getAttributeNo(np->node, i);
889 attname = (char *)NPDOM.getNodeName(attnode);
890 if ( !strcmp(name, attname) ) {
891 NPDOM.freeName(attnode, attname);
892 *rval = JSVAL_TRUE;
893 return TRUE;
894 };
895 NPDOM.freeName(attnode, attname);
896 };
897 *rval = JSVAL_FALSE;
898 return TRUE;
899 }
900 else {
901 return FALSE;
902 }
903 }
904
905 JSPropertySpec elementProps[] =
906 {
907 {"tagName", 0, PROP_OPT, eleGetTagName, NULL},
908 {NULL, 0, 0, 0, 0}
909 };
910
911 JSFunctionSpec elementFunctions[] =
912 {
913 {"getAttribute", eleGetAttribute, 0, 0, 0},
914 {"setAttribute", nodeUnsupported, 0, 0, 0},
915 {"removeAttribute", nodeUnsupported, 0, 0, 0},
916 {"getAttributeNode", eleGetAttributeNode, 0, 0, 0},
917 {"setAttributeNode", nodeUnsupported, 0, 0, 0},
918 {"removeAttributeNode", nodeUnsupported, 0, 0, 0},
919 {"getElementsByTagName", eleGetElementsByTagName, 0, 0, 0},
920 {"getAttributeNS", nodeUnsupported, 0, 0, 0},
921 {"setAttributeNS", nodeUnsupported, 0, 0, 0},
922 {"removeAttributeNS", nodeUnsupported, 0, 0, 0},
923 {"getAttributeNodeNS", nodeUnsupported, 0, 0, 0},
924 {"setAttributeNodeNS", nodeUnsupported, 0, 0, 0},
925 {"getElementsByTagNameNS", nodeUnsupported, 0, 0, 0},
926 {"hasAttribute", eleHasAttribute, 0, 0, 0},
927 {"hasAttributeNS", nodeUnsupported, 0, 0, 0},
928 {NULL, 0, 0, 0, 0}
929 };
930
931 /********************* Attr ************************/
932
933 JSClass attrClass = {
934 "Attr",
935 JSCLASS_HAS_PRIVATE,
936 JS_PropertyStub, JS_PropertyStub,
937 JS_PropertyStub,
938 JS_PropertyStub,
939 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
940 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
941 };
942
JS_PROP(attrGetSpecified)943 JS_PROP(attrGetSpecified)
944 {
945 *rval = JSVAL_TRUE;
946 return TRUE;
947 }
948
JS_PROP(attrGetOwnerElement)949 JS_PROP(attrGetOwnerElement)
950 {
951 declPRIV;
952 if (np) {
953 JSObject *o = jsdom_createNode(cx, np, NPDOM.getParent(np->node));
954 *rval = o ? OBJECT_TO_JSVAL(o) : JSVAL_NULL;
955 return TRUE;
956 }
957 else {
958 return FALSE;
959 }
960 }
961
962 JSPropertySpec attrProps[] = {
963 {"name", 0, PROP_OPT, nodeGetNodeName, NULL},
964 {"value", 0, PROP_OPT, nodeGetNodeValue, NULL},
965 {"specified", 0, PROP_OPT, attrGetSpecified, NULL},
966 {"ownerElement", 0, PROP_OPT, attrGetOwnerElement, NULL},
967 {NULL, 0, 0, 0, 0}
968 };
969
970 /******************* character data & Co. **********/
971
972 JSClass chardataClass = {
973 "CharacterData",
974 JSCLASS_HAS_PRIVATE,
975 JS_PropertyStub, JS_PropertyStub,
976 JS_PropertyStub,
977 JS_PropertyStub,
978 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
979 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
980 };
981
JS_PROP(chardataGetData)982 JS_PROP(chardataGetData)
983 {
984 declPRIV;
985 if (np) {
986 char *val = (char *)NPDOM.getNodeValue(np->node);
987 if (val) {
988 JSString *jval = JS_NewStringCopyZ(cx, val);
989 *rval = STRING_TO_JSVAL(jval);
990 } else {
991 *rval = JSVAL_NULL;
992 }
993 NPDOM.freeValue(np->node, val);
994 return TRUE;
995 }
996 else {
997 return FALSE;
998 }
999 }
1000
_getDataLen(const char * data)1001 int _getDataLen(const char* data)
1002 {
1003 return strlen((char *)data);
1004 }
1005
JS_PROP(chardataGetLength)1006 JS_PROP(chardataGetLength)
1007 {
1008 declPRIV;
1009 if (np) {
1010 const char* val = NPDOM.getNodeValue(np->node);
1011 *rval = INT_TO_JSVAL(_getDataLen(val));
1012 NPDOM.freeValue(np->node, (char*)val);
1013 return TRUE;
1014 }
1015 else {
1016 return FALSE;
1017 }
1018 }
1019
JS_METHOD(chardataSubstringData)1020 JS_METHOD(chardataSubstringData)
1021 {
1022 declPRIV;
1023 if (argc < 2)
1024 {
1025 JS_ReportError(cx,
1026 "CharacterData.substringData must have two parameters");
1027 return FALSE;
1028 }
1029 if (np) {
1030 const char *val = NPDOM.getNodeValue(np->node);
1031 int len = _getDataLen(val);
1032 int off = JSVAL_TO_INT(argv[0]);
1033 int count = JSVAL_TO_INT(argv[1]);
1034 JSString *str;
1035 if (off >= len)
1036 {
1037 str = JS_NewStringCopyZ(cx, "");
1038 }
1039 else
1040 {
1041 if (off + count > len) count = len - off;
1042 str = JS_NewStringCopyN(cx, val + off, count);
1043 }
1044 NPDOM.freeValue(np->node, (char*)val);
1045 *rval = STRING_TO_JSVAL(str);
1046 return TRUE;
1047 }
1048 else {
1049 return FALSE;
1050 }
1051 }
1052
1053 JSPropertySpec chardataProps[] =
1054 {
1055 {"data", 0, PROP_OPT, chardataGetData, NULL},
1056 {"length", 0, PROP_OPT, chardataGetLength, NULL},
1057 {NULL, 0, 0, 0, 0}
1058 };
1059
1060 JSFunctionSpec chardataFunctions[] =
1061 {
1062 {"substringData", chardataSubstringData, 0, 0, 0},
1063 {"appendData", nodeUnsupported, 0, 0, 0},
1064 {"insertData", nodeUnsupported, 0, 0, 0},
1065 {"deleteData", nodeUnsupported, 0, 0, 0},
1066 {"replaceData", nodeUnsupported, 0, 0, 0},
1067 {NULL, 0, 0, 0, 0}
1068 };
1069
1070 /********************* text ************************/
1071
1072 JSClass textClass = {
1073 "Text",
1074 JSCLASS_HAS_PRIVATE,
1075 JS_PropertyStub, JS_PropertyStub,
1076 JS_PropertyStub,
1077 JS_PropertyStub,
1078 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1079 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1080 };
1081
1082 JSFunctionSpec textFunctions[] =
1083 {
1084 {"splitText", nodeUnsupported, 0, 0, 0},
1085 {NULL, 0, 0, 0, 0}
1086 };
1087
1088 /******************** cdata ************************/
1089
1090 JSClass cdataClass = {
1091 "CDATASection",
1092 JSCLASS_HAS_PRIVATE,
1093 JS_PropertyStub, JS_PropertyStub,
1094 JS_PropertyStub,
1095 JS_PropertyStub,
1096 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1097 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1098 };
1099
1100 /***************** comment *************************/
1101
1102 JSClass commentClass = {
1103 "Comment",
1104 JSCLASS_HAS_PRIVATE,
1105 JS_PropertyStub, JS_PropertyStub,
1106 JS_PropertyStub,
1107 JS_PropertyStub,
1108 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1109 nodeFinalize, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1110 };
1111
1112 /********************* named node map **************/
1113
JS_PROP(nnmGetLength)1114 JS_PROP(nnmGetLength)
1115 {
1116 JSIdArray *arr = JS_Enumerate(cx, obj);
1117 *rval = INT_TO_JSVAL(arr -> length - 1);
1118 JS_DestroyIdArray(cx, arr);
1119 return TRUE;
1120 }
1121
JS_METHOD(nnmGetNamedItem)1122 JS_METHOD(nnmGetNamedItem)
1123 {
1124 JSBool rv;
1125 if (argc != 1)
1126 {
1127 JS_ReportError(cx, "NamedNodeMap.getNamedItem must have one parameter");
1128 return FALSE;
1129 }
1130 JSString *str = JSVAL_TO_STRING(argv[0]);
1131 jsval value;
1132 char *name = JS_GetStringBytes(str);
1133 rv = JS_GetProperty(cx, obj, name, &value);
1134 if (rv) *rval = value;
1135 return rv;
1136 }
1137
JS_METHOD(nnmSetNamedItem)1138 JS_METHOD(nnmSetNamedItem)
1139 {
1140 if (argc != 1)
1141 {
1142 JS_ReportError(cx, "NamedNodeMap.setNamedItem must have one parameter");
1143 return FALSE;
1144 }
1145 //check the type here!!!
1146 JSObject *nobj = JSVAL_TO_OBJECT(argv[0]);
1147 JSClass *cls = JS_GET_CLASS(cx, nobj);
1148 JSObject *proto = JS_GetPrototype(cx, nobj);
1149 JSContextItem *cxi = (JSContextItem*)JS_GetContextPrivate(cx);
1150 if (proto == cxi->node || cls == &nodeClass)
1151 {
1152 NodePrivate *np = (NodePrivate*)JS_GetPrivate(cx, nobj);
1153 char *name = (char *)NPDOM.getNodeName(np->node);
1154 JS_SetProperty(cx, obj, name, &(argv[0]));
1155 NPDOM.freeName(np->node,name);
1156 return TRUE;
1157 }
1158 else
1159 {
1160 JS_ReportError(cx, "invalid NamedNodeMap.setNamedItem parameter");
1161 return FALSE;
1162 }
1163 }
1164
JS_METHOD(nnmRemoveNamedItem)1165 JS_METHOD(nnmRemoveNamedItem)
1166 {
1167 if (argc != 1)
1168 {
1169 JS_ReportError(cx, "NamedNodeMap.removeNamedItem must have one parameter");
1170 return FALSE;
1171 }
1172 JSString *str = JSVAL_TO_STRING(argv[0]);
1173 char *name = JS_GetStringBytes(str);
1174 return JS_DeleteProperty(cx, obj, name);
1175 }
1176
JS_METHOD(nnmItem)1177 JS_METHOD(nnmItem)
1178 {
1179 if (argc >= 1 || ! JSVAL_IS_INT(argv[0]) )
1180 {
1181 JSIdArray *arr = JS_Enumerate(cx, obj);
1182 int idx = JSVAL_TO_INT(argv[0]);
1183 if (idx < 0 || idx >= arr -> length - 1)
1184 {
1185 *rval = JSVAL_VOID;
1186 }
1187 else
1188 {
1189 jsval val;
1190 //skip the 'length' property
1191 JS_IdToValue(cx, arr->vector[idx + 1], &val);
1192 JS_GetProperty(cx, obj,
1193 JS_GetStringBytes(JSVAL_TO_STRING(val)), rval);
1194 }
1195 JS_DestroyIdArray(cx, arr);
1196 return TRUE;
1197 }
1198 else
1199 {
1200 JS_ReportError(cx, "NamedNodeMap.item must have one parameter");
1201 return FALSE;
1202 }
1203 }
1204
1205 JSPropertySpec nnmProps[] = {
1206 {"length", 0, PROP_OPT, nnmGetLength, NULL},
1207 {NULL, 0, 0, 0, 0}
1208 };
1209
1210 JSFunctionSpec nnmFunctions[] = {
1211 {"getNamedItem", nnmGetNamedItem, 0, 0, 0},
1212 {"setNamedItem", nnmSetNamedItem, 0, 0, 0},
1213 {"removeNamedItem", nnmRemoveNamedItem, 0, 0, 0},
1214 {"item", nnmItem, 0, 0, 0},
1215 {"getNamedItemsNS", nodeUnsupported, 0, 0, 0},
1216 {"setNamedItemsNS", nodeUnsupported, 0, 0, 0},
1217 {"removeNamedItemsNS", nodeUnsupported, 0, 0, 0},
1218 {NULL, 0, 0, 0, 0}
1219 };
1220
1221 JSClass nnmClass = {
1222 "NamedNodeMap", 0,
1223 JS_PropertyStub,
1224 JS_PropertyStub,
1225 JS_PropertyStub,
1226 JS_PropertyStub,
1227 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
1228 JS_FinalizeStub, 0, 0, NULL, NULL, NULL, NULL, 0, 0
1229 };
1230
1231 /********************* functions *******************/
1232
_jsdom_getNodeClass(SDOM_NodeType type)1233 JSClass* _jsdom_getNodeClass(SDOM_NodeType type)
1234 {
1235 JSClass *cls;
1236 switch (type)
1237 {
1238 case SDOM_ELEMENT_NODE:
1239 cls = &elementClass;
1240 break;
1241 case SDOM_DOCUMENT_NODE:
1242 cls = &documentClass;
1243 break;
1244 case SDOM_ATTRIBUTE_NODE:
1245 cls = &attrClass;
1246 break;
1247 case SDOM_TEXT_NODE:
1248 cls = &textClass;
1249 break;
1250 case SDOM_CDATA_SECTION_NODE:
1251 cls = &cdataClass;
1252 break;
1253 case SDOM_COMMENT_NODE:
1254 cls = &commentClass;
1255 break;
1256 default:
1257 {
1258 cls = &nodeClass;
1259 }
1260 }
1261 return cls;
1262 }
1263
_jsdom_getNodeClass(Sit S,JSContext * cx,NodeHandle node)1264 JSClass* _jsdom_getNodeClass(Sit S, JSContext *cx, NodeHandle node)
1265 {
1266 return _jsdom_getNodeClass((SDOM_NodeType)S.dom().getNodeType(node));
1267 }
1268
jsdom_wrapNode(Sit S,JSContext * cx,NodeHandle node)1269 JSObject* jsdom_wrapNode(Sit S, JSContext *cx, NodeHandle node)
1270 {
1271 JSObject *obj = NULL;
1272 if (node)
1273 {
1274 JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1275 sabassert(item);
1276
1277 SDOM_NodeType type = (SDOM_NodeType)S.dom().getNodeType(node);
1278
1279 obj = JS_NewObject(cx, _jsdom_getNodeClass(type),
1280 item->node, NULL);
1281 JS_SetPrivate(cx, obj, _jsdom_getNodePrivate(S, node));
1282
1283 //common methods and properties
1284 JS_DefineProperties(cx, obj, nodeProps);
1285 JS_DefineFunctions(cx, obj, nodeFunctions);
1286
1287 //tweak the class
1288 switch (type)
1289 {
1290 case SDOM_ELEMENT_NODE:
1291 {
1292 JS_DefineProperties(cx, obj, elementProps);
1293 JS_DefineFunctions(cx, obj, elementFunctions);
1294 }; break;
1295 case SDOM_DOCUMENT_NODE:
1296 {
1297 JS_DefineProperties(cx, obj, documentProps);
1298 JS_DefineFunctions(cx, obj, documentFunctions);
1299 }; break;
1300 case SDOM_ATTRIBUTE_NODE:
1301 {
1302 JS_DefineProperties(cx, obj, attrProps);
1303 }; break;
1304 case SDOM_TEXT_NODE:
1305 {
1306 JS_DefineProperties(cx, obj, chardataProps);
1307 JS_DefineFunctions(cx, obj, chardataFunctions);
1308 //text specs.
1309 JS_DefineFunctions(cx, obj, textFunctions);
1310 }; break;
1311 case SDOM_CDATA_SECTION_NODE:
1312 {
1313 JS_DefineProperties(cx, obj, chardataProps);
1314 JS_DefineFunctions(cx, obj, chardataFunctions);
1315 }; break;
1316 case SDOM_COMMENT_NODE:
1317 {
1318 JS_DefineProperties(cx, obj, chardataProps);
1319 JS_DefineFunctions(cx, obj, chardataFunctions);
1320 }; break;
1321 }
1322 }
1323 return obj;
1324 }
1325
jsdom_createNode(JSContext * cx,NodePrivate * np_,NodeHandle node)1326 JSObject* jsdom_createNode(JSContext *cx, NodePrivate *np_, NodeHandle node)
1327 {
1328 return jsdom_wrapNode(*(np_->situa), cx, node);
1329 }
1330
1331
jsdom_delegateDOM(JSContext * cx)1332 void jsdom_delegateDOM(JSContext *cx)
1333 {
1334 JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1335 JSObject *obj;
1336 //Node prototype
1337 obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "Node",
1338 &nodeClass, NULL,
1339 JSPROP_ENUMERATE |
1340 JSPROP_READONLY |
1341 JSPROP_PERMANENT);
1342 JS_DefineProperties(cx, obj, nodeProtoProps);
1343 item -> node = obj;
1344 //DOMException prototype
1345 obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "DOMException",
1346 &domexClass, NULL,
1347 JSPROP_ENUMERATE |
1348 JSPROP_READONLY |
1349 JSPROP_PERMANENT);
1350 JS_DefineProperties(cx, obj, domexProtoProps);
1351 item -> domex = obj;
1352 //DOMImplementation
1353 obj = JS_DefineObject(cx, JS_GetGlobalObject(cx), "DOMImplementation",
1354 &domexClass, NULL,
1355 JSPROP_ENUMERATE |
1356 JSPROP_READONLY |
1357 JSPROP_PERMANENT);
1358 JS_DefineFunctions(cx, obj, domimplFunctions);
1359 item -> domimpl = obj;
1360 //nodelist class
1361 JSObject *nlclass = JS_InitClass(cx, JS_GetGlobalObject(cx),
1362 NULL,
1363 &nlistClass, nlistConstructor, 0,
1364 NULL, NULL, NULL, NULL);
1365 item -> nlclass = nlclass;
1366 //nodelist class
1367 // JSObject *nnmclass = JS_InitClass(cx, JS_GetGlobalObject(cx),
1368 // NULL,
1369 // &nnmClass, NULL, 0,
1370 // NULL, nnmFunctions, NULL, NULL);
1371 // item -> nnmclass = nnmclass;
1372 }
1373
jsdom_raiseException(JSContext * cx,int code)1374 void jsdom_raiseException(JSContext *cx, int code)
1375 {
1376 JSContextItem *item = (JSContextItem*)JS_GetContextPrivate(cx);
1377 sabassert(item);
1378
1379 JSObject *obj = JS_NewObject(cx, &domexClass, item -> domex, NULL);
1380 //set private
1381 DomExPrivate *c = new DomExPrivate;
1382 c -> code = code;
1383 JS_SetPrivate(cx, obj, c);
1384 //instance props. and funcs.
1385 JS_DefineProperties(cx, obj, domexProps);
1386 JS_DefineFunctions(cx, obj, domexFunctions);
1387 //raise exception
1388 JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
1389 }
1390
jsdom_createNodeList(JSContext * cx,int num)1391 JSObject* jsdom_createNodeList(JSContext *cx, int num)
1392 {
1393 //JSObject *obj = JS_NewArrayObject(cx, 0, NULL);
1394 //JS_DefineFunctions(cx, obj, nlistFunctions);
1395 JSObject *obj = JS_ConstructObject(cx, &nlistClass, NULL, NULL);
1396
1397 return obj;
1398 }
1399
jsdom_createNamedNodeMap(JSContext * cx,int num)1400 JSObject* jsdom_createNamedNodeMap(JSContext *cx, int num)
1401 {
1402 JSObject *obj = JS_NewObject(cx, &nnmClass, NULL, NULL);
1403 JS_DefineFunctions(cx, obj, nnmFunctions);
1404 JS_DefineProperties(cx, obj, nnmProps);
1405
1406 return obj;
1407 }
1408
1409 #endif //ENABLE_JS
1410